aboutsummaryrefslogtreecommitdiff
path: root/coreutils/printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/printf.c')
-rw-r--r--coreutils/printf.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c
index ebe961564..b7752369c 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -193,6 +193,7 @@ static char **print_formatted(char *f, char **argv)
193 unsigned direc_length; /* Length of % directive. */ 193 unsigned direc_length; /* Length of % directive. */
194 int field_width; /* Arg to first '*', or -1 if none. */ 194 int field_width; /* Arg to first '*', or -1 if none. */
195 int precision; /* Arg to second '*', or -1 if none. */ 195 int precision; /* Arg to second '*', or -1 if none. */
196 char **saved_argv = argv;
196 197
197 for (; *f; ++f) { 198 for (; *f; ++f) {
198 switch (*f) { 199 switch (*f) {
@@ -264,8 +265,9 @@ static char **print_formatted(char *f, char **argv)
264 precision, ""); 265 precision, "");
265 break; 266 break;
266 case '\\': 267 case '\\':
267 if (*++f == 'c') 268 if (*++f == 'c') {
268 exit(EXIT_SUCCESS); 269 return saved_argv; /* causes main() to exit */
270 }
269 bb_putchar(bb_process_escape_sequence((const char **)&f)); 271 bb_putchar(bb_process_escape_sequence((const char **)&f));
270 f--; 272 f--;
271 break; 273 break;
@@ -277,12 +279,22 @@ static char **print_formatted(char *f, char **argv)
277 return argv; 279 return argv;
278} 280}
279 281
280int printf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
281int printf_main(int argc ATTRIBUTE_UNUSED, char **argv) 282int printf_main(int argc ATTRIBUTE_UNUSED, char **argv)
282{ 283{
283 char *format; 284 char *format;
284 char **argv2; 285 char **argv2;
285 286
287 /* We must check that stdout is not closed.
288 * The reason for this is highly non-obvious. printf_main is used from shell.
289 * Shell must correctly handle 'printf "%s" foo'
290 * if stdout is closed. With stdio, output gets shoveled into
291 * stdout buffer, and even fflush cannot clear it out. It seems that
292 * even if libc receives EBADF on write attempts, it feels determined
293 * to output data no matter what. So it will try later,
294 * and possibly will clobber future output. Not good. */
295 if (dup2(1, 1) != 1)
296 return -1;
297
286 /* bash builtin errors out on "printf '-%s-\n' foo", 298 /* bash builtin errors out on "printf '-%s-\n' foo",
287 * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo". 299 * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo".
288 * We will mimic coreutils. */ 300 * We will mimic coreutils. */