Subject: bug#11540: [PATCH] tee: add a flag to ignore SIGPIPE

From: Igor Ippolitov <[email-masked]>
Date: Tue, 22 May 2012 18:00:39 +0400

>From 89c055b385a9d4f4804af6b7b3fbe67651471613 Mon Sep 17 00:00:00 2001
From: Ippolitov A. Igor <[email-masked]>
Date: Tue, 22 May 2012 17:58:23 +0400
Subject: [PATCH] tee: add a flag to ignore SIGPIPE

* src/tee.c: added ignore_sigpipes variable and -p
             and --ignore-sigpipes options

If we call tee like:
program | tee file1 file2 | head -3
just to be sure there some output from program started. Or like:
program | tee >(head -1) file1 file2
We'll get SIGPIPE on writing to a file. It can be undesirable
behaviour: file1 and file2 would be incomplete.
Running with -i won't correct this.
"-p|--ignore-sigpipes" options will make tee ignore any sigpipe
it can receive. So file1 and file2 would have complete output.
---
 src/tee.c |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/src/tee.c b/src/tee.c
index 2d82577..0021174 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -43,10 +43,14 @@ static bool append;
 /* If true, ignore interrupts. */
 static bool ignore_interrupts;

+/* if true, ignore sigpipe signal. */
+static bool ignore_sigpipes;
+
 static struct option const long_options[] =
 {
   {"append", no_argument, NULL, 'a'},
   {"ignore-interrupts", no_argument, NULL, 'i'},
+  {"ignore-sigpipes", no_argument, NULL, 'p'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -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\
   -i, --ignore-interrupts   ignore interrupt signals\n\
+  -p, --ignore-sigpipe      ignore pipe signals\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -93,8 +98,9 @@ main (int argc, char **argv)

   append = false;
   ignore_interrupts = false;
+  ignore_sigpipes = 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)
         {
@@ -106,6 +112,10 @@ main (int argc, char **argv)
           ignore_interrupts = true;
           break;

+        case 'p':
+          ignore_sigpipes = true;
+          break;
+
         case_GETOPT_HELP_CHAR;

         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -116,7 +126,14 @@ main (int argc, char **argv)
     }

   if (ignore_interrupts)
+    {
     signal (SIGINT, SIG_IGN);
+    }
+
+  if (ignore_sigpipes)
+    {
+    signal (SIGPIPE, SIG_IGN);
+    }

   /* Do *not* warn if tee is given no file arguments.
      POSIX requires that it work when given no arguments.  */
-- 
1.7.0.4