SIGPIPE propagation

Pieter de Goeje pieter at degoeje.nl
Sat Mar 1 15:40:28 UTC 2008


On Saturday 01 March 2008, Martin Laabs wrote:
> Hello,
>
> as you probably know I want to expand dump in such
> a way it enableds multivolume dumps also when the
> output data is written to stdout/a pipe.
> Now I ran into a serious problem.
> Dump counts the written bytes to remember where
> it has to proceede after the volumen change.
> Now the SIGPIPE signal does not propagate fast
> enought through the system. Thus dump writes
> some time after the pipe has got broken data into
> the pipe while it doesn't exist anymore. This short
> time it does not receive any error about that.
> (Until the signal propagates to dump.)
> I wrote a small test progam to demonstrate this
> effect (and get clear about it by myself). It just
> write data to stdout and counts it until the pipe
> is broken (and the write call will return -1) This
> is the output of a few successively runs:

This problem cannot be solved using sigpipe. You will always have a race 
condition because the reader's only way of notifying the writer that it 
shouldn't write anymore is through closing the pipe, after which the reader 
cannot read any remaining data that was just written to the pipe buffer.

Given ./a.out | asdf

Consider the fact that when you create a pipe, both ends are open. At this 
point it is possible to write a small amount of data to the pipe without 
blocking, because of the pipe buffer. The reader intends to close the pipe as 
soon as possible (command does not exist). Which of these events occurs first 
is however undefined, so sometimes a.out succeeds in writing data and 
sometimes it doesn't.

writer                  reader
 |                        |
 write() (succeeds)       |
 |                       close()
 |                        |
 sigpipe()                |
 write() (fails)          |

The data in the pipe is now lost.

>
>
> $ ./a.out |asdf
> $ asdf: command not found
> cought broken pipe
> i: 12 could only wrote -1 bytes. total wrote: 61440
>
> $ ./a.out |asdf
> $ asdf: command not found
> cought broken pipe
> i: 1 could only wrote -1 bytes. total wrote: 5120
>
> $ ./a.out |asdf
> $ asdf: command not found
> cought broken pipe
> i: 12 could only wrote -1 bytes. total wrote: 61440
>
> $ ./a.out |asdf
> $ asdf: command not found
> cought broken pipe
> i: 0 could only wrote -1 bytes. total wrote: 0


-- 
Pieter de Goeje



More information about the freebsd-hackers mailing list