Module Name: src Committed By: riastradh Date: Sun Feb 9 17:10:37 UTC 2025
Modified Files: src/tests/lib/libc/sys: Makefile t_poll.c Log Message: t_poll: Expand tests of polling when other endpoint is closed. This covers fifos, pipes, and sockets; reads and writes; and polling when the endpoint is already closed as well as sleeping until the endpoint is closed after a delay. Unfortunately, there is disagreement right now between: (a) POSIX, (b) our poll(2) man page, and (c) our implementation, for many of these cases. And we recently changed the behaviour of poll(2) on fifos between 9 and 10 (PR kern/56429: poll(2) should yield POLLHUP when last writer to a fifo close()'s it) but didn't get it quite right. So I've annotated these test cases with xfails for all the cases I think we're currently doing wrong -- under a justification from some combination of POSIX, our own documentation, and/or a reasonable interpretation of what the semantics _should_ be based on how read(2) and write(2) will behave. These are mostly edge cases: 1. [pollclosed_pipe_*_write*] When the read side of a pipe is closed, poll(2) on the write side currently returns POLLHUP|POLLOUT, which POSIX forbids because it requires POLLHUP to be mutually exclusive with POLLOUT. And our man page concurs with POSIX on this rule, and has for a long time (going as far back as NetBSD 1.3 or earlier, judging by https://man.NetBSD.org/NetBSD-1.3/poll.2). => Fixing this won't change whether anything wakes up earlier or later -- it will only change which bits are set when the wakeups happen. 2. [pollclosed_fifo*_immediate_readsome] When the write side of a fifo was previously open with the read side, and has since been closed before calling poll(2), poll(2) on the read side returns 0 instead of POLLHUP|POLLIN as it is expected to, even though read(2) will return EOF without blocking. => Fixing this may lead to more wakeups than before, but only in cases where read(2) would actually return immediately anyway. 3. [pollclosed_fifo*_delayed_*_read] When the write side of a fifo is closed, poll(2) on the read side returns POLLHUP|POLLIN, as it is expected to. But this state currently isn't persistent, even though the behaviour of read(2) in returning EOF without blocking is persistent. => Fixing this may lead to more wakeups than before, but only in cases where read(2) would actually return immediately anyway. That said, it turns out that we are correct, according to POSIX, in not setting POLLHUP on a socket whose peer has been closed: POLLHUP is only for devices, pipes, and FIFOs. So one of the issues I reported in PR 59056 turns out to be bogus. (Also POLLHUP is only for the reader side anyway, not for the writer side.) https://pubs.opengroup.org/onlinepubs/9799919799/functions/poll.html PR kern/59056: poll POLLHUP bugs To generate a diff of this commit: cvs rdiff -u -r1.77 -r1.78 src/tests/lib/libc/sys/Makefile cvs rdiff -u -r1.10 -r1.11 src/tests/lib/libc/sys/t_poll.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.