On Mon, 21 Sept 2026 at 09:08, Taylor R Campbell <[email protected]> wrote:
> 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
