diff options
author | Denis Vlasenko | 2008-06-01 22:36:39 +0000 |
---|---|---|
committer | Denis Vlasenko | 2008-06-01 22:36:39 +0000 |
commit | cd2663f15e74274619dd97dc382bb858ac255872 (patch) | |
tree | f86565e574c3488794383b910b9f3fa3ae27df48 /coreutils/printf.c | |
parent | d78920675f31d6ec87dc883c4edc0f3862b22f6a (diff) | |
download | busybox-cd2663f15e74274619dd97dc382bb858ac255872.zip busybox-cd2663f15e74274619dd97dc382bb858ac255872.tar.gz |
ash: optional printf builtin. +25 bytes if off, +35 if on.
by Cristian Ionescu-Idbohrn.
Diffstat (limited to 'coreutils/printf.c')
-rw-r--r-- | coreutils/printf.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c index ebe9615..b775236 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -193,6 +193,7 @@ static char **print_formatted(char *f, char **argv) unsigned direc_length; /* Length of % directive. */ int field_width; /* Arg to first '*', or -1 if none. */ int precision; /* Arg to second '*', or -1 if none. */ + char **saved_argv = argv; for (; *f; ++f) { switch (*f) { @@ -264,8 +265,9 @@ static char **print_formatted(char *f, char **argv) precision, ""); break; case '\\': - if (*++f == 'c') - exit(EXIT_SUCCESS); + if (*++f == 'c') { + return saved_argv; /* causes main() to exit */ + } bb_putchar(bb_process_escape_sequence((const char **)&f)); f--; break; @@ -277,12 +279,22 @@ static char **print_formatted(char *f, char **argv) return argv; } -int printf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int printf_main(int argc ATTRIBUTE_UNUSED, char **argv) { char *format; char **argv2; + /* We must check that stdout is not closed. + * The reason for this is highly non-obvious. printf_main is used from shell. + * Shell must correctly handle 'printf "%s" foo' + * if stdout is closed. With stdio, output gets shoveled into + * stdout buffer, and even fflush cannot clear it out. It seems that + * even if libc receives EBADF on write attempts, it feels determined + * to output data no matter what. So it will try later, + * and possibly will clobber future output. Not good. */ + if (dup2(1, 1) != 1) + return -1; + /* bash builtin errors out on "printf '-%s-\n' foo", * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo". * We will mimic coreutils. */ |