Created attachment 189130 [details] patch for filt_piperead When connecting as a new reader to a named pipe after all previous writers have disconnected, EVFILT_READ currently returns EV_EOF. poll(2) was fixed a while ago so that it won't return POLLHUP in this case (at least since r238936). The attached patch brings the logic in EVFILT_READ in sync with poll(2) again. I wonder why the other side of the pipe is also checked in EVFILT_READ. Wouldn't it be enough to just check for EOF on the readers side? This would be consistent with sockets for example (where just SBS_CANTRCVMORE leads to EV_EOF). I've also attached a small patch to the pipepoll.c regression test that can be used to reproduce the issue.
Created attachment 189131 [details] patch to pipepoll.c demonstrating the issue
Created attachment 213659 [details] Updated FIFO/pipe fixes I've been running these FIFO/pipe fixes for some time now. I've attached the current version of the patch. This should also fix https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203366 and some other minor issues I've come across. I wrote a lot of ATF tests for FIFO/pipe behavior with kqueue/poll here: https://github.com/jiixyj/epoll-shim/blob/develop/test/pipe-test.c . I'd love to clean them up for inclusion into FreeBSD. Currently there is lots of code to test FIFOs/pipes under other operating systems as well which obscures the important stuff a bit.
Created attachment 213662 [details] Updated FIFO/pipe fixes (more context) I've regenerated the patch with more context (git show -U999999).
(In reply to Jan Kokemüller from comment #3) Ah, excellent, thanks! =-) Any chance you have a Phabricator account and would be willing to upload it there, as well, so we can loop in some other folks?
Sure thing, I've opened https://reviews.freebsd.org/D24528 !
A commit references this bug: Author: markj Date: Mon Apr 27 15:59:20 UTC 2020 New revision: 360380 URL: https://svnweb.freebsd.org/changeset/base/360380 Log: Fix handling of EV_EOF for named pipes. Contrary to the kevent man page, EV_EOF on a fifo is not cleared by EV_CLEAR. Modify the read and write filters to clear EV_EOF when the fifo's PIPE_EOF flag is clear, and update the man page to document the new behaviour. Modify the write filter to return the amount of buffer space available even if no readers are present. This matches the behaviour for sockets. When reading from a pipe, only call pipeselwakeup() if some data was actually read. This prevents the continuous re-triggering of a EVFILT_READ event on EOF when in edge-triggered mode. PR: 203366, 224615 Submitted by: Jan Kokem?ller <jan.kokemueller@gmail.com> MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D24528 Changes: head/lib/libc/sys/kqueue.2 head/sys/kern/sys_pipe.c
A commit references this bug: Author: markj Date: Mon May 11 15:20:41 UTC 2020 New revision: 360897 URL: https://svnweb.freebsd.org/changeset/base/360897 Log: MFC r360380: Fix handling of EV_EOF for named pipes. PR: 203366, 224615, 246350 Changes: _U stable/12/ stable/12/lib/libc/sys/kqueue.2 stable/12/sys/kern/sys_pipe.c