aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-06-18 22:22:04 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-06-18 22:22:04 +0200
commitbf4aeed129ba7518be04ab9e53073bdb737a24b8 (patch)
tree3a98fa58c9d7fc378560b9717c44a97d30c3edfd /coreutils
parentc9f280cc469daccfc0eba20bca6a1341070230b6 (diff)
downloadbusybox-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.c24
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
62typedef void FAST_FUNC (*converter)(const char *arg, void *result); 59typedef 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. */
244static char **print_formatted(char *f, char **argv) 239static 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
357int printf_main(int argc UNUSED_PARAM, char **argv) 352int 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}