Subject: bug#14246: tee can't continue when receiving SIGPIPE + adding a text mode option

From: Camion SPAM <[email-masked]>
Date: Tue, 23 Apr 2013 13:57:00 +0100 (BST)

Hello, I could like to suggest the following patch for tee.
It addresses the following problems : 
1/ Add a new -t parametre to have tee work line per line instead of block by block (Usefull if you use tee to check script results while they are sent to a file or anywhere else
2/ Ignores SIGPIPE so that it can close a broken pipe and continue tee-ing on others.
This is useful when you write things like this 

$(some_command | tee /dev/fd/3 | some_processing_1) 3>&1 | processing_2_not_reading_up_to_the_end

In this case, when processing_2 stops reading, tee will receive SIGPIPE and will be killed preventing processing_1 from receiving it's data.

Philippe Errembault

44a45,48
> /* If true, read input line per line instead of block per block */
> static bool text_mode;
>
>
48a53
>   {"text-mode", no_argument, NULL, 't'},
67a73
>   -t, --text-mode           copy input line per line instead of block per block\n\
97c103
<   while ((optc = getopt_long (argc, argv, "ai", long_options, NULL)) != -1)
---
>   while ((optc = getopt_long (argc, argv, "ait", long_options, NULL)) != -1)
108a115,118
>       case 't':
>         text_mode=true;
>           break;
119a130
>   signal (SIGPIPE, SIG_IGN);
182c193,198
<       bytes_read = read (0, buffer, sizeof buffer);
---
>       if (text_mode)
>       {
>         bytes_read=0;
>         while (bytes_read<sizeof buffer)
>           {
>           ssize_t br = read(0, buffer+bytes_read, 1);
184,185c200,201
<       if (bytes_read < 0 && errno == EINTR)
<         continue;
--->           if (br < 0 && errno == EINTR)

>             continue;
186a203,221
>           if (br <= 0)
>             {
>             if (bytes_read==0)
>               bytes_read=br;
>             break;
>             }
>
>           if (buffer[bytes_read++] == '\n')
>             break;
>           }
>       }
>       else
>         {
>         bytes_read = read (0, buffer, sizeof buffer);
> #ifdef EINTR
>         if (bytes_read < 0 && errno == EINTR)
>           continue;
> #endif
>         }