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",

Reply via email to