--- tee-orig.c Fri Jun 7 16:32:34 2002 +++ tee.c Fri Jun 7 16:34:15 2002 @@ -37,6 +37,9 @@ /* If nonzero, append to output files rather than truncating them. */ static int append; +/* If nonzero, output to stderr as well. */ +static int out_stderr; + /* If nonzero, ignore interrupts. */ static int ignore_interrupts; @@ -46,6 +49,7 @@ static struct option const long_options[] = { {"append", no_argument, NULL, 'a'}, + {"stderr", no_argument, NULL, 'e'}, {"ignore-interrupts", no_argument, NULL, 'i'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -65,6 +69,7 @@ Copy standard input to each FILE, and also to standard output.\n\ \n\ -a, --append append to the given FILEs, do not overwrite\n\ + -e, --stderr output to standard error as well\n\ -i, --ignore-interrupts ignore interrupt signals\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); @@ -88,9 +93,10 @@ atexit (close_stdout); append = 0; + out_stderr = 0; ignore_interrupts = 0; - while ((optc = getopt_long (argc, argv, "ai", long_options, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "aei", long_options, NULL)) != -1) { switch (optc) { @@ -101,6 +107,10 @@ append = 1; break; + case 'e': + out_stderr = 1; + break; + case 'i': ignore_interrupts = 1; break; @@ -164,24 +174,37 @@ char buffer[BUFSIZ]; int bytes_read, i; int ret = 0; + int nbstdfiles = 1; const char *mode_string = (append ? "a" : "w"); + + if ( out_stderr ) + nbstdfiles += 1; - descriptors = (FILE **) xmalloc ((nfiles + 1) * sizeof (descriptors[0])); + descriptors = (FILE **) xmalloc ((nfiles + nbstdfiles) * + sizeof (descriptors[0])); /* Move all the names `up' one in the argv array to make room for - the entry for standard output. This writes into argv[argc]. */ - for (i = nfiles; i >= 1; i--) - files[i] = files[i - 1]; + the entry for standard output (and standard error, if requested). + This writes into argv[argc]. */ + for (i = nfiles; i >= nbstdfiles; i--) + files[i] = files[i - nbstdfiles]; SET_BINARY2 (0, 1); - /* In the array of NFILES + 1 descriptors, make - the first one correspond to standard output. */ + /* In the array of NFILES + nbstdfile descriptors, make the first one + correspond to standard output (and the second one correspond to standard + error, if requested). */ descriptors[0] = stdout; files[0] = _("standard output"); SETVBUF (stdout, NULL, _IONBF, 0); - for (i = 1; i <= nfiles; i++) + if ( out_stderr ) { + descriptors[1] = stderr; + files[1] = _("standard error"); + SETVBUF (stderr, NULL, _IONBF, 0); + } + + for (i = nbstdfiles; i < (nfiles + nbstdfiles); i++) { descriptors[i] = fopen (files[i], mode_string); if (descriptors[i] == NULL) @@ -206,9 +229,9 @@ if (bytes_read <= 0) break; - /* Write to all NFILES + 1 descriptors. + /* Write to all NFILES + nbstdfiles descriptors. Standard output is the first one. */ - for (i = 0; i <= nfiles; i++) + for (i = 0; i < (nfiles + nbstdfiles); i++) { if (descriptors[i] != NULL) fwrite (buffer, bytes_read, 1, descriptors[i]); @@ -221,8 +244,8 @@ ret = 1; } - /* Close the files, but not standard output. */ - for (i = 1; i <= nfiles; i++) + /* Close the files, but not standard output, nor standard error. */ + for (i = nbstdfiles; i < (nfiles + nbstdfiles); i++) if (descriptors[i] != NULL && (ferror (descriptors[i]) || fclose (descriptors[i]) == EOF)) {