git: 6b90209aaf80 - main - tests: ensure that unix/stream raises POLLIN after a shutdown(2)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 31 May 2025 00:04:57 UTC
The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=6b90209aaf809204c62e2a252c931e7240f60374 commit 6b90209aaf809204c62e2a252c931e7240f60374 Author: Kyle Evans <kevans@FreeBSD.org> AuthorDate: 2025-05-31 00:04:33 +0000 Commit: Kyle Evans <kevans@FreeBSD.org> CommitDate: 2025-05-31 00:04:33 +0000 tests: ensure that unix/stream raises POLLIN after a shutdown(2) This tests for the bug fixed in 6ac71c4a52348 ("unix/stream: fix poll on a peer shutdown(2)ed socket"), where-in the remote side has shutdown writes on their side and the other end fails to return from select(2)/poll(2) because we weren't surfacing it as readable. Reviewed by: adrian, kib Differential Revision: https://reviews.freebsd.org/D50602 --- tests/sys/kern/unix_stream.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/sys/kern/unix_stream.c b/tests/sys/kern/unix_stream.c index 9f750967ebf8..f8ba288308bd 100644 --- a/tests/sys/kern/unix_stream.c +++ b/tests/sys/kern/unix_stream.c @@ -28,6 +28,7 @@ #include <sys/cdefs.h> #include <sys/socket.h> #include <sys/event.h> +#include <sys/select.h> #include <sys/sysctl.h> #include <sys/un.h> #include <errno.h> @@ -101,6 +102,20 @@ ATF_TC_BODY(send_0, tc) close(sv[1]); } +static void +check_readable_select(int fd, int expect, bool timeout) +{ + fd_set rdfds; + int nfds; + + FD_ZERO(&rdfds); + FD_SET(fd, &rdfds); + nfds = select(fd + 1, &rdfds, NULL, NULL, timeout ? + &(struct timeval){.tv_usec = 1000} : NULL); + ATF_REQUIRE_MSG(nfds == expect, + "select() returns %d errno %d", nfds, errno); +} + static void check_writable_select(int fd, int expect, bool timeout) { @@ -115,6 +130,21 @@ check_writable_select(int fd, int expect, bool timeout) "select() returns %d errno %d", nfds, errno); } +static void +check_readable_poll(int fd, int expect, bool timeout) +{ + struct pollfd pfd[1]; + int nfds; + + pfd[0] = (struct pollfd){ + .fd = fd, + .events = POLLIN | POLLRDNORM, + }; + nfds = poll(pfd, 1, timeout ? 1 : INFTIM); + ATF_REQUIRE_MSG(nfds == expect, + "poll() returns %d errno %d", nfds, errno); +} + static void check_writable_poll(int fd, int expect, bool timeout) { @@ -325,6 +355,31 @@ ATF_TC_BODY(peershutdown_writability, tc) close(sv[1]); } +ATF_TC_WITHOUT_HEAD(peershutdown_readability); +ATF_TC_BODY(peershutdown_readability, tc) +{ + ssize_t readsz; + int sv[2]; + char c; + + do_socketpair(sv); + shutdown(sv[1], SHUT_WR); + + /* + * The other side should flag as readable in select(2) to allow it to + * read(2) and observe EOF. Ensure that both poll(2) and select(2) + * are consistent here. + */ + check_readable_select(sv[0], 1, false); + check_readable_poll(sv[0], 1, false); + + readsz = read(sv[0], &c, sizeof(c)); + ATF_REQUIRE_INTEQ(0, readsz); + + close(sv[0]); + close(sv[1]); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, getpeereid); @@ -336,6 +391,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, full_writability_kevent); ATF_TP_ADD_TC(tp, peerclosed_writability); ATF_TP_ADD_TC(tp, peershutdown_writability); + ATF_TP_ADD_TC(tp, peershutdown_readability); return atf_no_error(); }