diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-06-18 22:22:04 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-06-18 22:22:04 +0200 |
| commit | bf4aeed129ba7518be04ab9e53073bdb737a24b8 (patch) | |
| tree | 3a98fa58c9d7fc378560b9717c44a97d30c3edfd /coreutils | |
| parent | c9f280cc469daccfc0eba20bca6a1341070230b6 (diff) | |
| download | busybox-w32-bf4aeed129ba7518be04ab9e53073bdb737a24b8.tar.gz busybox-w32-bf4aeed129ba7518be04ab9e53073bdb737a24b8.tar.bz2 busybox-w32-bf4aeed129ba7518be04ab9e53073bdb737a24b8.zip | |
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 2beea7189..5b326c643 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c | |||
| @@ -53,10 +53,7 @@ | |||
| 53 | * (but negative numbers are not "bad"). | 53 | * (but negative numbers are not "bad"). |
| 54 | * Both accept negative numbers for %u specifier. | 54 | * Both accept negative numbers for %u specifier. |
| 55 | * | 55 | * |
| 56 | * We try to be compatible. We are not compatible here: | 56 | * We try to be compatible. |
| 57 | * - we do not accept -NUM for %u | ||
| 58 | * - exit code is 0 even if "invalid number" was seen (FIXME) | ||
| 59 | * See "if (errno)" checks in the code below. | ||
| 60 | */ | 57 | */ |
| 61 | 58 | ||
| 62 | typedef void FAST_FUNC (*converter)(const char *arg, void *result); | 59 | typedef void FAST_FUNC (*converter)(const char *arg, void *result); |
| @@ -163,7 +160,6 @@ static void print_direc(char *format, unsigned fmt_length, | |||
| 163 | case 'i': | 160 | case 'i': |
| 164 | llv = my_xstrtoll(argument); | 161 | llv = my_xstrtoll(argument); |
| 165 | print_long: | 162 | print_long: |
| 166 | /* if (errno) return; - see comment at the top */ | ||
| 167 | if (!have_width) { | 163 | if (!have_width) { |
| 168 | if (!have_prec) | 164 | if (!have_prec) |
| 169 | printf(format, llv); | 165 | printf(format, llv); |
| @@ -210,7 +206,6 @@ static void print_direc(char *format, unsigned fmt_length, | |||
| 210 | case 'g': | 206 | case 'g': |
| 211 | case 'G': | 207 | case 'G': |
| 212 | dv = my_xstrtod(argument); | 208 | dv = my_xstrtod(argument); |
| 213 | /* if (errno) return; */ | ||
| 214 | if (!have_width) { | 209 | if (!have_width) { |
| 215 | if (!have_prec) | 210 | if (!have_prec) |
| 216 | printf(format, dv); | 211 | printf(format, dv); |
| @@ -241,7 +236,7 @@ static int get_width_prec(const char *str) | |||
| 241 | 236 | ||
| 242 | /* Print the text in FORMAT, using ARGV for arguments to any '%' directives. | 237 | /* Print the text in FORMAT, using ARGV for arguments to any '%' directives. |
| 243 | Return advanced ARGV. */ | 238 | Return advanced ARGV. */ |
| 244 | static char **print_formatted(char *f, char **argv) | 239 | static char **print_formatted(char *f, char **argv, int *conv_err) |
| 245 | { | 240 | { |
| 246 | char *direc_start; /* Start of % directive. */ | 241 | char *direc_start; /* Start of % directive. */ |
| 247 | unsigned direc_length; /* Length of % directive. */ | 242 | unsigned direc_length; /* Length of % directive. */ |
| @@ -299,8 +294,8 @@ static char **print_formatted(char *f, char **argv) | |||
| 299 | 294 | ||
| 300 | /* Remove "lLhz" size modifiers, repeatedly. | 295 | /* Remove "lLhz" size modifiers, repeatedly. |
| 301 | * bash does not like "%lld", but coreutils | 296 | * bash does not like "%lld", but coreutils |
| 302 | * would happily take even "%Llllhhzhhzd"! | 297 | * happily takes even "%Llllhhzhhzd"! |
| 303 | * We will be permissive like coreutils */ | 298 | * We are permissive like coreutils */ |
| 304 | while ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') { | 299 | while ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') { |
| 305 | overlapping_strcpy(f, f + 1); | 300 | overlapping_strcpy(f, f + 1); |
| 306 | } | 301 | } |
| @@ -330,12 +325,12 @@ static char **print_formatted(char *f, char **argv) | |||
| 330 | } | 325 | } |
| 331 | if (*argv) { | 326 | if (*argv) { |
| 332 | print_direc(direc_start, direc_length, field_width, | 327 | print_direc(direc_start, direc_length, field_width, |
| 333 | precision, *argv); | 328 | precision, *argv++); |
| 334 | ++argv; | ||
| 335 | } else { | 329 | } else { |
| 336 | print_direc(direc_start, direc_length, field_width, | 330 | print_direc(direc_start, direc_length, field_width, |
| 337 | precision, ""); | 331 | precision, ""); |
| 338 | } | 332 | } |
| 333 | *conv_err |= errno; | ||
| 339 | free(p); | 334 | free(p); |
| 340 | } | 335 | } |
| 341 | break; | 336 | break; |
| @@ -356,6 +351,7 @@ static char **print_formatted(char *f, char **argv) | |||
| 356 | 351 | ||
| 357 | int printf_main(int argc UNUSED_PARAM, char **argv) | 352 | int printf_main(int argc UNUSED_PARAM, char **argv) |
| 358 | { | 353 | { |
| 354 | int conv_err; | ||
| 359 | char *format; | 355 | char *format; |
| 360 | char **argv2; | 356 | char **argv2; |
| 361 | 357 | ||
| @@ -392,9 +388,10 @@ int printf_main(int argc UNUSED_PARAM, char **argv) | |||
| 392 | format = argv[1]; | 388 | format = argv[1]; |
| 393 | argv2 = argv + 2; | 389 | argv2 = argv + 2; |
| 394 | 390 | ||
| 391 | conv_err = 0; | ||
| 395 | do { | 392 | do { |
| 396 | argv = argv2; | 393 | argv = argv2; |
| 397 | argv2 = print_formatted(format, argv); | 394 | argv2 = print_formatted(format, argv, &conv_err); |
| 398 | } while (argv2 > argv && *argv2); | 395 | } while (argv2 > argv && *argv2); |
| 399 | 396 | ||
| 400 | /* coreutils compat (bash doesn't do this): | 397 | /* coreutils compat (bash doesn't do this): |
| @@ -402,5 +399,6 @@ int printf_main(int argc UNUSED_PARAM, char **argv) | |||
| 402 | fprintf(stderr, "excess args ignored"); | 399 | fprintf(stderr, "excess args ignored"); |
| 403 | */ | 400 | */ |
| 404 | 401 | ||
| 405 | return (argv2 < argv); /* if true, print_formatted errored out */ | 402 | return (argv2 < argv) /* if true, print_formatted errored out */ |
| 403 | || conv_err; /* print_formatted saw invalid number */ | ||
| 406 | } | 404 | } |
