aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/printf.c22
-rwxr-xr-xtestsuite/printf.tests6
2 files changed, 19 insertions, 9 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c
index a14306f5a..d877e0581 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -33,7 +33,8 @@
33 The 'format' argument is re-used as many times as necessary 33 The 'format' argument is re-used as many times as necessary
34 to convert all of the given arguments. 34 to convert all of the given arguments.
35 35
36 David MacKenzie <djm@gnu.ai.mit.edu> */ 36 David MacKenzie <djm@gnu.ai.mit.edu>
37*/
37 38
38 39
39// 19990508 Busy Boxed! Dave Cinege 40// 19990508 Busy Boxed! Dave Cinege
@@ -251,10 +252,12 @@ static char **print_formatted(char *f, char **argv)
251 ++f; 252 ++f;
252 ++direc_length; 253 ++direc_length;
253 } 254 }
254 /* 255 /* needed - try "printf %" without it */
255 if (!strchr ("diouxXfeEgGcs", *f)) 256 if (!strchr("diouxXfeEgGcs", *f)) {
256 fprintf(stderr, "%%%c: invalid directive", *f); 257 bb_error_msg("invalid directive '%s'", direc_start);
257 */ 258 /* causes main() to exit with error */
259 return saved_argv - 1;
260 }
258 ++direc_length; 261 ++direc_length;
259 if (*argv) { 262 if (*argv) {
260 print_direc(direc_start, direc_length, field_width, 263 print_direc(direc_start, direc_length, field_width,
@@ -285,7 +288,8 @@ int printf_main(int argc UNUSED_PARAM, char **argv)
285 char **argv2; 288 char **argv2;
286 289
287 /* We must check that stdout is not closed. 290 /* We must check that stdout is not closed.
288 * The reason for this is highly non-obvious. printf_main is used from shell. 291 * The reason for this is highly non-obvious.
292 * printf_main is used from shell.
289 * Shell must correctly handle 'printf "%s" foo' 293 * Shell must correctly handle 'printf "%s" foo'
290 * if stdout is closed. With stdio, output gets shoveled into 294 * if stdout is closed. With stdio, output gets shoveled into
291 * stdout buffer, and even fflush cannot clear it out. It seems that 295 * stdout buffer, and even fflush cannot clear it out. It seems that
@@ -298,7 +302,7 @@ int printf_main(int argc UNUSED_PARAM, char **argv)
298 /* bash builtin errors out on "printf '-%s-\n' foo", 302 /* bash builtin errors out on "printf '-%s-\n' foo",
299 * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo". 303 * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo".
300 * We will mimic coreutils. */ 304 * We will mimic coreutils. */
301 if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && argv[1][2] == '\0') 305 if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && !argv[1][2])
302 argv++; 306 argv++;
303 if (!argv[1]) 307 if (!argv[1])
304 bb_show_usage(); 308 bb_show_usage();
@@ -309,12 +313,12 @@ int printf_main(int argc UNUSED_PARAM, char **argv)
309 do { 313 do {
310 argv = argv2; 314 argv = argv2;
311 argv2 = print_formatted(format, argv); 315 argv2 = print_formatted(format, argv);
312 } while (argv2 != argv && *argv2); 316 } while (argv2 > argv && *argv2);
313 317
314 /* coreutils compat (bash doesn't do this): 318 /* coreutils compat (bash doesn't do this):
315 if (*argv) 319 if (*argv)
316 fprintf(stderr, "excess args ignored"); 320 fprintf(stderr, "excess args ignored");
317 */ 321 */
318 322
319 return EXIT_SUCCESS; 323 return (argv2 < argv); /* if true, print_formatted errored out */
320} 324}
diff --git a/testsuite/printf.tests b/testsuite/printf.tests
index 18f25e3f1..d6b60fb8c 100755
--- a/testsuite/printf.tests
+++ b/testsuite/printf.tests
@@ -24,4 +24,10 @@ testing "printf repeatedly use pattern for each argv" \
24 "foo\n$HOME\n" \ 24 "foo\n$HOME\n" \
25 "" "" 25 "" ""
26 26
27# Why ()s are necessary I have no idea...
28testing "printf aborts on bare %" \
29 "(${bb}printf '%' a b c) 2>&1; echo \$?" \
30 "printf: invalid directive '%'\n""1\n" \
31 "" ""
32
27exit $FAILCOUNT 33exit $FAILCOUNT