Sometimes I run (say) git log or hg log with a query that takes a long
time to produce output into my pager, less(1).
When I type `q' to exit the pager, sometimes the producer is still
_computing_ but not _writing_ output. In this case, it doesn't notice
that its job is done until it next tries to _write_ output and the
write fails with EPIPE/SIGPIPE. So the producer just hangs doing
computation until it has another byte of output to write -- which will
be summarily discarded as soon as it is written.
This is annoying: after I hit `q', if I want the producer to exit
promptly, I sometimes have to hit ^C or ^\ to interrupt it manually.
How can or should applications do this right, so that the producer can
subscribe to a notification of when the consumer of a pipeline has
(exited and) closed the reading side of the pipe, instead of only
getting a notification when the producer next tries to write output?
Answers, with references, accepted for either: (a) what actually works
reliably (not just by accident) on NetBSD and other operating systems,
(b) what is justified by the letter of POSIX, or (c) what is justified
by historical design intent. Bonus if it also works reliably for
sockets, named pipes, ptys, and ttys.
[snip] yup, this is something that's been annoying both in POSIX pipes
and sockets (think half closed sockets, sigh) since forever.
You're right, you don't get a notification about the write end of a
pipe or socket being unavailable until (a) you're bidirectional
and get read ready + EOF (but for half closed sockets that's not
always a guarantee that you should finish writing), or (b) it's time
to write a byte and the other end is finally seen as dead.
So I don't think there's a POSIX way to do it. You may be able to craft
something up using kqueue? I wonder if FreeBSD's kqueue implementation
does something when this happens, like set KQ_EOF or similar on
the write side of a pipe.
-adrian