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

From: Pádraig Brady <[email-masked]>
Date: Tue, 22 May 2012 18:32:41 +0100

On 05/22/2012 06:18 PM, Pádraig Brady wrote:
> On 05/22/2012 03:00 PM, Igor Ippolitov wrote:
>> >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.  */
> 
> 
> I checked back and there was a very similar patch nearly 4 years ago.
> http://lists.gnu.org/archive/html/bug-coreutils/2008-10/msg00067.html
> I think there was general agreement in the thread on its merits.
> 
> I wonder though, would a higher level option be more appropriate?
> I think what's being configured here is whether to exit early on write error,
> whether it is to one of the files or stdout. Why would you want
> to treat them differently? Also you could get SIGPIPEs I think
> if one of the files was >(a process).
> 
> The default would be to diagnose write errors,
> and that could be changed with:
> 
> --write-error={[cont],ignore,exit}

I just looked at a recent proposal that overlaps with the above nicely:
http://lists.gnu.org/archive/html/coreutils/2012-05/msg00070.html

cheers,
Pádraig.