diff options
author | Denys Vlasenko | 2009-06-18 22:22:04 +0200 |
---|---|---|
committer | Denys Vlasenko | 2009-06-18 22:22:04 +0200 |
commit | bf4aeed129ba7518be04ab9e53073bdb737a24b8 (patch) | |
tree | 3a98fa58c9d7fc378560b9717c44a97d30c3edfd /coreutils | |
parent | c9f280cc469daccfc0eba20bca6a1341070230b6 (diff) | |
download | busybox-bf4aeed129ba7518be04ab9e53073bdb737a24b8.zip busybox-bf4aeed129ba7518be04ab9e53073bdb737a24b8.tar.gz |
printf: fix exit code on conversion error
Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/printf.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c index 2beea71..5b326c6 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -53,10 +53,7 @@ * (but negative numbers are not "bad"). * Both accept negative numbers for %u specifier. * - * We try to be compatible. We are not compatible here: - * - we do not accept -NUM for %u - * - exit code is 0 even if "invalid number" was seen (FIXME) - * See "if (errno)" checks in the code below. + * We try to be compatible. */ typedef void FAST_FUNC (*converter)(const char *arg, void *result); @@ -163,7 +160,6 @@ static void print_direc(char *format, unsigned fmt_length, case 'i': llv = my_xstrtoll(argument); print_long: - /* if (errno) return; - see comment at the top */ if (!have_width) { if (!have_prec) printf(format, llv); @@ -210,7 +206,6 @@ static void print_direc(char *format, unsigned fmt_length, case 'g': case 'G': dv = my_xstrtod(argument); - /* if (errno) return; */ if (!have_width) { if (!have_prec) printf(format, dv); @@ -241,7 +236,7 @@ static int get_width_prec(const char *str) /* Print the text in FORMAT, using ARGV for arguments to any '%' directives. Return advanced ARGV. */ -static char **print_formatted(char *f, char **argv) +static char **print_formatted(char *f, char **argv, int *conv_err) { char *direc_start; /* Start of % directive. */ unsigned direc_length; /* Length of % directive. */ @@ -299,8 +294,8 @@ static char **print_formatted(char *f, char **argv) /* Remove "lLhz" size modifiers, repeatedly. * bash does not like "%lld", but coreutils - * would happily take even "%Llllhhzhhzd"! - * We will be permissive like coreutils */ + * happily takes even "%Llllhhzhhzd"! + * We are permissive like coreutils */ while ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') { overlapping_strcpy(f, f + 1); } @@ -330,12 +325,12 @@ static char **print_formatted(char *f, char **argv) } if (*argv) { print_direc(direc_start, direc_length, field_width, - precision, *argv); - ++argv; + precision, *argv++); } else { print_direc(direc_start, direc_length, field_width, precision, ""); } + *conv_err |= errno; free(p); } break; @@ -356,6 +351,7 @@ static char **print_formatted(char *f, char **argv) int printf_main(int argc UNUSED_PARAM, char **argv) { + int conv_err; char *format; char **argv2; @@ -392,9 +388,10 @@ int printf_main(int argc UNUSED_PARAM, char **argv) format = argv[1]; argv2 = argv + 2; + conv_err = 0; do { argv = argv2; - argv2 = print_formatted(format, argv); + argv2 = print_formatted(format, argv, &conv_err); } while (argv2 > argv && *argv2); /* coreutils compat (bash doesn't do this): @@ -402,5 +399,6 @@ int printf_main(int argc UNUSED_PARAM, char **argv) fprintf(stderr, "excess args ignored"); */ - return (argv2 < argv); /* if true, print_formatted errored out */ + return (argv2 < argv) /* if true, print_formatted errored out */ + || conv_err; /* print_formatted saw invalid number */ } |