Say we have a named pipe called fifo
, and we're reading and writing to it from two different shells. Consider these two examples:
shell 1$ echo foo > fifo
<hangs>
shell 2$ cat fifo
foo
shell 1$ echo bar > fifo
<hangs>
shell 1$ cat > fifo
<typing> foo
<hangs>
shell 2$ cat fifo
foo
^C
shell 1$
<typing> bar
<exits>
I can't wrap my head around what happens in these examples, and in particular why trying to write 'bar' to the pipe in the first example results in a blocking call, whereas in the second example it triggers a SIGPIPE.
I do understand that in the first case, two separate processes write to the pipe, and thus it is opened twice, while in the second case it is only opened once by a single process and written to twice, with the process reading from the pipe being killed in the meantime. What I don't understand is how that affects the behaviour of write
.
The pipe(7)
man page states:
If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process.
This condition doesn't sound clear to me. A closed file descriptor just ceases to be a file descriptor, right? How does saying "the reading end of the pipe has been closed" differ from "the reading end of the pipe is not open"?
I hope my question was clear enough. By the way, if you could suggest pointers for understanding in details the functioning of Unix pipes in relationship to open
, close
, read
and write
operations, I'd greatly appreciate it.