Andreas Schwab wrote: > > How about adding an option '-p' to 'tee', that causes it to ignore SIGPIPE > > while writing to stdout? > > Just add a trap '' SIGPIPE before starting tee.
Thanks, this does half of the trick: Each 'tee' invocation then writes the complete stdin contents to the log file. But each 'tee' invocation also complains: tee: standard output: Broken pipe tee: write error tee: standard output: Broken pipe tee: write error ... I don't see any better solution than putting support for this into 'tee' itself. Jim, here's a patch. From 9813ded2983b0a7f276dc249e68a246bf9c1686a Mon Sep 17 00:00:00 2001 From: Bruno Haible <[EMAIL PROTECTED]> Date: Tue, 1 Jul 2008 02:22:10 +0200 Subject: [PATCH] New tee option -p. * src/tee.c (ignore_sigpipe): New variable. (long_options): Add option -p. (usage): Document option -p. (main): Handle option -p. (tee_files): When option -p is specified, ignore SIGPIPE write errors. * doc/coreutils.texi (tee invocation): Document option -p. --- doc/coreutils.texi | 11 +++++++++++ src/tee.c | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 155ba8d..c5d7745 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -11341,6 +11341,17 @@ them. @opindex --ignore-interrupts Ignore interrupt signals. [EMAIL PROTECTED] -p [EMAIL PROTECTED] --ignore-sigpipe [EMAIL PROTECTED] -p [EMAIL PROTECTED] --ignore-sigpipe +Ignore failed writes to pipes with no readers. By default, when standard +output or one of the given files refers to a pipe with no reading processes, +the operating system will kill the @command{tee} process with signal [EMAIL PROTECTED], thus terminating the output to the other files. When the +option @samp{-p} is specified, the @command{tee} process will continue +writing to the other specified files. + @end table The @command{tee} command is useful when you happen to be transferring a large diff --git a/src/tee.c b/src/tee.c index 4e46aab..85f4529 100644 --- a/src/tee.c +++ b/src/tee.c @@ -41,10 +41,14 @@ static bool append; /* If true, ignore interrupts. */ static bool ignore_interrupts; +/* If true, ignore failed writes to pipes with no readers. */ +static bool ignore_sigpipe; + static struct option const long_options[] = { {"append", no_argument, NULL, 'a'}, {"ignore-interrupts", no_argument, NULL, 'i'}, + {"ignore-sigpipe", no_argument, NULL, 'p'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -64,6 +68,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\ -i, --ignore-interrupts ignore interrupt signals\n\ + -p, --ignore-sigpipe ignore failed writes to pipes with no readers\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); @@ -93,7 +98,7 @@ main (int argc, char **argv) append = false; ignore_interrupts = false; - while ((optc = getopt_long (argc, argv, "ai", long_options, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1) { switch (optc) { @@ -105,6 +110,10 @@ main (int argc, char **argv) ignore_interrupts = true; break; + case 'p': + ignore_sigpipe = true; + break; + case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); @@ -117,6 +126,11 @@ main (int argc, char **argv) if (ignore_interrupts) signal (SIGINT, SIG_IGN); +#ifdef SIGPIPE + if (ignore_sigpipe) + signal (SIGPIPE, SIG_IGN); +#endif + /* Do *not* warn if tee is given no file arguments. POSIX requires that it work when given no arguments. */ @@ -192,9 +206,25 @@ tee_files (int nfiles, const char **files) if (descriptors[i] && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1) { - error (0, errno, "%s", files[i]); - descriptors[i] = NULL; - ok = false; +#ifdef SIGPIPE + if (ignore_sigpipe && errno == EPIPE) + { + /* Could not write to a pipe with no readers. + Close the stream. */ + fclose (descriptors[i]); + /* Close also the underlying file descriptor, to avoid an + error message from close_stdout. */ + if (fileno (descriptors[i]) >= 0) + close (fileno (descriptors[i])); + descriptors[i] = NULL; + } + else +#endif + { + error (0, errno, "%s", files[i]); + descriptors[i] = NULL; + ok = false; + } } } -- 1.5.5.3 _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils