From 2d27e4ccbbc29d6ec1b907849984cec30f24e734 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 25 Nov 2006 23:50:28 +0000 Subject: tee: fix bug: argv[-1] is a no-no! bb_full_fd_action: optimize die_if_ferror: ": filename" isn't a good err msg, add "..I/O error" --- coreutils/tee.c | 76 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'coreutils/tee.c') diff --git a/coreutils/tee.c b/coreutils/tee.c index 06c94aba6..640a231ef 100644 --- a/coreutils/tee.c +++ b/coreutils/tee.c @@ -17,67 +17,66 @@ int tee_main(int argc, char **argv) { const char *mode = "w\0a"; FILE **files; - FILE **p; - char **filenames; + FILE **fp; + char **names; + char **np; int flags; int retval = EXIT_SUCCESS; -#ifdef CONFIG_FEATURE_TEE_USE_BLOCK_IO +#if ENABLE_FEATURE_TEE_USE_BLOCK_IO ssize_t c; # define buf bb_common_bufsiz1 #else int c; #endif - flags = getopt32(argc, argv, "ia"); /* 'a' must be 2nd */ + argc -= optind; + argv += optind; mode += (flags & 2); /* Since 'a' is the 2nd option... */ if (flags & 1) { - signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction.*/ + signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction. */ } - /* gnu tee ignores SIGPIPE in case one of the output files is a pipe * that doesn't consume all its input. Good idea... */ - signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/ + signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction. */ /* Allocate an array of FILE *'s, with one extra for a sentinal. */ - p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2)); - *p = stdout; - argv += optind - 1; - filenames = argv - 1; - *filenames = (char *) bb_msg_standard_input; /* for later */ - goto GOT_NEW_FILE; + fp = files = xzalloc(sizeof(FILE *) * (argc + 2)); + np = names = argv - 1; + files[0] = stdout; + goto GOT_NEW_FILE; do { - if ((*p = fopen_or_warn(*argv, mode)) == NULL) { + *fp = fopen_or_warn(*argv, mode); + if (*fp == NULL) { retval = EXIT_FAILURE; continue; } - filenames[(int)(p - files)] = *argv; - GOT_NEW_FILE: - setbuf(*p, NULL); /* tee must not buffer output. */ - ++p; - } while (*++argv); - - *p = NULL; /* Store the sentinal value. */ - -#ifdef CONFIG_FEATURE_TEE_USE_BLOCK_IO + *np = *argv++; + GOT_NEW_FILE: + setbuf(*fp++, NULL); /* tee must not buffer output. */ + np++; + } while (*argv); + /* names[0] will be filled later */ + +#if ENABLE_FEATURE_TEE_USE_BLOCK_IO while ((c = safe_read(STDIN_FILENO, buf, BUFSIZ)) > 0) { - for (p=files ; *p ; p++) { - fwrite(buf, 1, c, *p); - } + fp = files; + do + fwrite(buf, 1, c, *fp++); + while (*fp); } - - if (c < 0) { /* Make sure read errors are signaled. */ + if (c < 0) { /* Make sure read errors are signaled. */ retval = EXIT_FAILURE; } - #else setvbuf(stdout, NULL, _IONBF, 0); while ((c = getchar()) != EOF) { - for (p=files ; *p ; p++) { - putc(c, *p); - } + fp = files; + do + putc(c, *fp++); + while (*fp); } #endif @@ -87,14 +86,15 @@ int tee_main(int argc, char **argv) * setting the first entry to stdin and checking stdout error * status with fflush_stdout_and_exit()... although fflush()ing * is unnecessary here. */ - - p = files; - *p = stdin; - do { /* Now check for (input and) output errors. */ + np = names; + fp = files; + names[0] = (char *) bb_msg_standard_input; + files[0] = stdin; + do { /* Now check for input and output errors. */ /* Checking ferror should be sufficient, but we may want to fclose. * If we do, remember not to close stdin! */ - die_if_ferror(*p, filenames[(int)(p - files)]); - } while (*++p); + die_if_ferror(*fp++, *np++); + } while (*fp); fflush_stdout_and_exit(retval); } -- cgit v1.2.3