Module Name: src Committed By: riastradh Date: Sun Feb 9 17:10:23 UTC 2025
Modified Files: src/tests/lib/libc/sys: t_poll.c Log Message: t_poll: Tweak to improve diagnostics. PR kern/59056: poll POLLHUP bugs To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 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.
Modified files: Index: src/tests/lib/libc/sys/t_poll.c diff -u src/tests/lib/libc/sys/t_poll.c:1.9 src/tests/lib/libc/sys/t_poll.c:1.10 --- src/tests/lib/libc/sys/t_poll.c:1.9 Sun Feb 9 17:09:51 2025 +++ src/tests/lib/libc/sys/t_poll.c Sun Feb 9 17:10:23 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: t_poll.c,v 1.9 2025/02/09 17:09:51 riastradh Exp $ */ +/* $NetBSD: t_poll.c,v 1.10 2025/02/09 17:10:23 riastradh Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -101,35 +101,33 @@ ATF_TC_BODY(3way, tc) int pf[2]; int status, i; pid_t pid; + ssize_t nwrit; - pipe(pf); + RL(pipe(pf)); desc = pf[0]; - pid = fork(); - ATF_REQUIRE(pid >= 0); - + RL(pid = fork()); if (pid == 0) { - (void)close(pf[1]); + if (close(pf[1]) == -1) + _exit(1); child1(); _exit(0); /* NOTREACHED */ } - pid = fork(); - ATF_REQUIRE(pid >= 0); - + RL(pid = fork()); if (pid == 0) { - (void)close(pf[1]); + if (close(pf[1]) == -1) + _exit(1); child2(); _exit(0); /* NOTREACHED */ } - pid = fork(); - ATF_REQUIRE( pid >= 0); - + RL(pid = fork()); if (pid == 0) { - (void)close(pf[1]); + if (close(pf[1]) == -1) + _exit(1); child3(); _exit(0); /* NOTREACHED */ @@ -139,10 +137,11 @@ ATF_TC_BODY(3way, tc) (void)printf("parent write\n"); - ATF_REQUIRE(write(pf[1], "konec\n", 6) == 6); + RL(nwrit = write(pf[1], "konec\n", 6)); + ATF_REQUIRE_EQ_MSG(nwrit, 6, "nwrit=%zd", nwrit); - for(i = 0; i < 3; ++i) - (void)wait(&status); + for (i = 0; i < 3; i++) + RL(wait(&status)); (void)printf("parent terminated\n"); } @@ -160,8 +159,9 @@ ATF_TC_BODY(basic, tc) int fds[2]; struct pollfd pfds[2]; int ret; + ssize_t nwrit; - ATF_REQUIRE_EQ(pipe(fds), 0); + RL(pipe(fds)); pfds[0].fd = fds[0]; pfds[0].events = POLLIN; @@ -174,16 +174,16 @@ ATF_TC_BODY(basic, tc) */ pfds[0].revents = -1; pfds[1].revents = -1; - ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0, - "got: %d", ret); + RL(ret = poll(&pfds[0], 1, 1)); + ATF_REQUIRE_EQ_MSG(ret, 0, "got: %d", ret); ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); /* Check that the write end of the pipe as reported as ready. */ pfds[0].revents = -1; pfds[1].revents = -1; - ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1, - "got: %d", ret); + RL(ret = poll(&pfds[1], 1, 1)); + ATF_REQUIRE_EQ_MSG(ret, 1, "got: %d", ret); ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ pfds[1].revents); @@ -191,27 +191,28 @@ ATF_TC_BODY(basic, tc) /* Check that only the write end of the pipe as reported as ready. */ pfds[0].revents = -1; pfds[1].revents = -1; - ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1, - "got: %d", ret); + RL(ret = poll(pfds, 2, 1)); + ATF_REQUIRE_EQ_MSG(ret, 1, "got: %d", ret); ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", pfds[1].revents); /* Write data to our pipe. */ - ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); + RL(nwrit = write(fds[1], "", 1)); + ATF_REQUIRE_EQ_MSG(nwrit, 1, "nwrit=%zd", nwrit); /* Check that both ends of our pipe are reported as ready. */ pfds[0].revents = -1; pfds[1].revents = -1; - ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2, - "got: %d", ret); + RL(ret = poll(pfds, 2, 1)); + ATF_REQUIRE_EQ_MSG(ret, 2, "got: %d", ret); ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", pfds[0].revents); ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", pfds[1].revents); - ATF_REQUIRE_EQ(close(fds[0]), 0); - ATF_REQUIRE_EQ(close(fds[1]), 0); + RL(close(fds[0])); + RL(close(fds[1])); } ATF_TC(err); @@ -240,9 +241,10 @@ static const char fifo_path[] = "pollhup static void fifo_support(void) { + errno = 0; if (mkfifo(fifo_path, 0600) == 0) { - ATF_REQUIRE(unlink(fifo_path) == 0); + RL(unlink(fifo_path)); return; } @@ -266,19 +268,20 @@ ATF_TC_BODY(fifo_inout, tc) char *buf; int rfd, wfd; long pipe_buf; + int ret; + ssize_t nwrit, nread; fifo_support(); - ATF_REQUIRE(mkfifo(fifo_path, 0600) == 0); - ATF_REQUIRE((rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)) >= 0); - ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY | O_NONBLOCK)) >= 0); + RL(mkfifo(fifo_path, 0600)); + RL(rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)); + RL(wfd = open(fifo_path, O_WRONLY | O_NONBLOCK)); /* Get the maximum atomic pipe write size. */ pipe_buf = fpathconf(wfd, _PC_PIPE_BUF); - ATF_REQUIRE(pipe_buf > 1); + ATF_REQUIRE_MSG(pipe_buf > 1, "pipe_buf=%ld", pipe_buf); - buf = malloc(pipe_buf); - ATF_REQUIRE(buf != NULL); + REQUIRE_LIBC(buf = malloc(pipe_buf), NULL); memset(&pfd, 0, sizeof(pfd)); pfd[0].fd = rfd; @@ -287,20 +290,28 @@ ATF_TC_BODY(fifo_inout, tc) pfd[1].events = POLLOUT | POLLWRNORM; /* We expect the FIFO to be writable but not readable. */ - ATF_REQUIRE(poll(pfd, 2, 0) == 1); - ATF_REQUIRE(pfd[0].revents == 0); - ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM)); + RL(ret = poll(pfd, 2, 0)); + ATF_REQUIRE_EQ_MSG(ret, 1, "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfd[0].revents, 0, + "pfd[0].revents=0x%x", pfd[0].revents); + ATF_REQUIRE_EQ_MSG(pfd[1].revents, POLLOUT|POLLWRNORM, + "pfd[1].revents=0x%x", pfd[1].revents); /* Write a single byte of data into the FIFO. */ - ATF_REQUIRE(write(wfd, buf, 1) == 1); + RL(nwrit = write(wfd, buf, 1)); + ATF_REQUIRE_EQ_MSG(nwrit, 1, "nwrit=%zd", nwrit); /* We expect the FIFO to be readable and writable. */ - ATF_REQUIRE(poll(pfd, 2, 0) == 2); - ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM)); - ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM)); + RL(ret = poll(pfd, 2, 0)); + ATF_REQUIRE_EQ_MSG(ret, 2, "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfd[0].revents, POLLIN|POLLRDNORM, + "pfd[0].revents=0x%x", pfd[0].revents); + ATF_REQUIRE_EQ_MSG(pfd[1].revents, POLLOUT|POLLWRNORM, + "pfd[1].revents=0x%x", pfd[1].revents); /* Read that single byte back out. */ - ATF_REQUIRE(read(rfd, buf, 1) == 1); + RL(nread = read(rfd, buf, 1)); + ATF_REQUIRE_EQ_MSG(nread, 1, "nread=%zd", nread); /* * Write data into the FIFO until it is full, which is @@ -310,33 +321,44 @@ ATF_TC_BODY(fifo_inout, tc) while (write(wfd, buf, pipe_buf) != -1) { continue; } - ATF_REQUIRE(errno == EAGAIN); + ATF_REQUIRE_EQ_MSG(errno, EAGAIN, "errno=%d", errno); /* We expect the FIFO to be readble but not writable. */ - ATF_REQUIRE(poll(pfd, 2, 0) == 1); - ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM)); - ATF_REQUIRE(pfd[1].revents == 0); + RL(ret = poll(pfd, 2, 0)); + ATF_REQUIRE_EQ_MSG(ret, 1, "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfd[0].revents, POLLIN|POLLRDNORM, + "pfd[0].revents=0x%x", pfd[0].revents); + ATF_REQUIRE_EQ_MSG(pfd[1].revents, 0, + "pfd[1].revents=0x%x", pfd[1].revents); /* Read a single byte of data from the FIFO. */ - ATF_REQUIRE(read(rfd, buf, 1) == 1); + RL(nread = read(rfd, buf, 1)); + ATF_REQUIRE_EQ_MSG(nread, 1, "nread=%zd", nread); /* * Because we have read only a single byte out, there will * be insufficient space for a pipe_buf-sized message, so * the FIFO should still not be writable. */ - ATF_REQUIRE(poll(pfd, 2, 0) == 1); - ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM)); - ATF_REQUIRE(pfd[1].revents == 0); + RL(ret = poll(pfd, 2, 0)); + ATF_REQUIRE_EQ_MSG(ret, 1, "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfd[0].revents, POLLIN|POLLRDNORM, + "pfd[0].revents=0x%x", pfd[0].revents); + ATF_REQUIRE_EQ_MSG(pfd[1].revents, 0, + "pfd[1].revents=0x%x", pfd[1].revents); /* * Now read enough so that exactly pipe_buf space should * be available. The FIFO should be writable after that. * N.B. we don't care if it's readable at this point. */ - ATF_REQUIRE(read(rfd, buf, pipe_buf - 1) == pipe_buf - 1); - ATF_REQUIRE(poll(pfd, 2, 0) >= 1); - ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM)); + RL(nread = read(rfd, buf, pipe_buf - 1)); + ATF_REQUIRE_EQ_MSG(nread, pipe_buf - 1, "nread=%zd pipe_buf-1=%ld", + nread, pipe_buf - 1); + RL(ret = poll(pfd, 2, 0)); + ATF_REQUIRE_MSG(ret >= 1, "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfd[1].revents, POLLOUT|POLLWRNORM, + "pfd[1].revents=0x%x", pfd[1].revents); /* * Now read all of the data out of the FIFO and ensure that @@ -345,14 +367,17 @@ ATF_TC_BODY(fifo_inout, tc) while (read(rfd, buf, pipe_buf) != -1) { continue; } - ATF_REQUIRE(errno == EAGAIN); + ATF_REQUIRE_EQ_MSG(errno, EAGAIN, "errno=%d", errno); - ATF_REQUIRE(poll(pfd, 2, 0) == 1); - ATF_REQUIRE(pfd[0].revents == 0); - ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM)); + RL(ret = poll(pfd, 2, 0)); + ATF_REQUIRE_EQ_MSG(ret, 1, "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfd[0].revents, 0, + "pfd[0].revents=0x%x", pfd[0].revents); + ATF_REQUIRE_EQ_MSG(pfd[1].revents, POLLOUT|POLLWRNORM, + "pfd[1].revents=0x%x", pfd[1].revents); - (void)close(wfd); - (void)close(rfd); + RL(close(wfd)); + RL(close(rfd)); } ATF_TC_CLEANUP(fifo_inout, tc) @@ -371,20 +396,22 @@ ATF_TC_BODY(fifo_hup1, tc) { struct pollfd pfd; int rfd, wfd; + int ret; fifo_support(); - ATF_REQUIRE(mkfifo(fifo_path, 0600) == 0); - ATF_REQUIRE((rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)) >= 0); - ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY)) >= 0); + RL(mkfifo(fifo_path, 0600)); + RL(rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)); + RL(wfd = open(fifo_path, O_WRONLY)); memset(&pfd, 0, sizeof(pfd)); pfd.fd = rfd; pfd.events = POLLIN; - (void)close(wfd); + RL(close(wfd)); - ATF_REQUIRE(poll(&pfd, 1, 0) == 1); + RL(ret = poll(&pfd, 1, 0)); + ATF_REQUIRE_EQ_MSG(ret, 1, "got: %d", ret); ATF_REQUIRE_EQ_MSG((pfd.revents & (POLLHUP|POLLOUT)), POLLHUP, "revents=0x%x expected POLLHUP=0x%x and not POLLOUT=0x%x", pfd.revents, POLLHUP, POLLOUT); @@ -398,8 +425,9 @@ ATF_TC_BODY(fifo_hup1, tc) pfd.fd = rfd; pfd.events = POLLIN; - ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY)) >= 0); - ATF_REQUIRE(poll(&pfd, 1, 0) == 0); + RL(wfd = open(fifo_path, O_WRONLY)); + RL(ret = poll(&pfd, 1, 0)); + ATF_REQUIRE_EQ_MSG(ret, 0, "got: %d", ret); } ATF_TC_CLEANUP(fifo_hup1, tc) @@ -420,34 +448,39 @@ ATF_TC_BODY(fifo_hup2, tc) int rfd, wfd; pid_t pid; struct timespec ts1, ts2; + int ret; fifo_support(); - ATF_REQUIRE(mkfifo(fifo_path, 0600) == 0); - ATF_REQUIRE((rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)) >= 0); - ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY)) >= 0); + RL(mkfifo(fifo_path, 0600)); + RL(rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)); + RL(wfd = open(fifo_path, O_WRONLY)); memset(&pfd, 0, sizeof(pfd)); pfd.fd = rfd; pfd.events = POLLIN; - pid = fork(); - ATF_REQUIRE(pid >= 0); - + RL(pid = fork()); if (pid == 0) { - (void)close(rfd); + if (close(rfd)) + _exit(1); sleep(5); - (void)close(wfd); + if (close(wfd)) + _exit(1); _exit(0); } - (void)close(wfd); + RL(close(wfd)); - ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts1) == 0); - ATF_REQUIRE(poll(&pfd, 1, INFTIM) == 1); - ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts2) == 0); + RL(clock_gettime(CLOCK_MONOTONIC, &ts1)); + RL(ret = poll(&pfd, 1, INFTIM)); + ATF_REQUIRE_EQ_MSG(ret, 1, "got: %d", ret); + RL(clock_gettime(CLOCK_MONOTONIC, &ts2)); /* Make sure at least a couple of seconds have elapsed. */ - ATF_REQUIRE(ts2.tv_sec - ts1.tv_sec >= 2); + ATF_REQUIRE_MSG(ts2.tv_sec - ts1.tv_sec >= 2, + "ts1=%lld.%09ld ts2=%lld.%09ld", + (long long)ts1.tv_sec, ts1.tv_nsec, + (long long)ts2.tv_sec, ts2.tv_nsec); ATF_REQUIRE_EQ_MSG((pfd.revents & (POLLHUP|POLLOUT)), POLLHUP, "revents=0x%x expected POLLHUP=0x%x and not POLLOUT=0x%x",