Module Name:    src
Committed By:   thorpej
Date:           Sat Oct  2 15:50:06 UTC 2021

Modified Files:
        src/tests/lib/libc/sys: t_poll.c

Log Message:
Add a fifo_inout test case that validates the expected POLLIN / POLLOUT
behavior for FIFOs:
- A FIFO is readable so long as at least 1 byte is available.
- A FIFO is writable so long as at least PIPE_BUF (obtained with _PC_PIPE_BUF)
  space is avaiable.

This will be cloned for a forthcoming kevent test case.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 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.6 src/tests/lib/libc/sys/t_poll.c:1.7
--- src/tests/lib/libc/sys/t_poll.c:1.6	Sat Oct  2 14:41:36 2021
+++ src/tests/lib/libc/sys/t_poll.c	Sat Oct  2 15:50:06 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_poll.c,v 1.6 2021/10/02 14:41:36 thorpej Exp $	*/
+/*	$NetBSD: t_poll.c,v 1.7 2021/10/02 15:50:06 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -39,6 +39,7 @@
 #include <paths.h>
 #include <poll.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <signal.h>
 #include <unistd.h>
 
@@ -252,6 +253,104 @@ fifo_support(void)
 	}
 }
 
+ATF_TC_WITH_CLEANUP(fifo_inout);
+ATF_TC_HEAD(fifo_inout, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Check POLLIN/POLLOUT behavior with fifos");
+}
+
+ATF_TC_BODY(fifo_inout, tc)
+{
+	struct pollfd pfd[2];
+	char *buf;
+	int rfd, wfd;
+	long pipe_buf;
+
+	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);
+
+	/* Get the maximum atomic pipe write size. */
+	pipe_buf = fpathconf(wfd, _PC_PIPE_BUF);
+	ATF_REQUIRE(pipe_buf > 1);
+
+	buf = malloc(pipe_buf);
+	ATF_REQUIRE(buf != NULL);
+
+	memset(&pfd, 0, sizeof(pfd));
+	pfd[0].fd = rfd;
+	pfd[0].events = POLLIN | POLLRDNORM;
+	pfd[1].fd = wfd;
+	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));
+
+	/* Write a single byte of data into the FIFO. */
+	ATF_REQUIRE(write(wfd, buf, 1) == 1);
+
+	/* 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));
+
+	/* Read that single byte back out. */
+	ATF_REQUIRE(read(rfd, buf, 1) == 1);
+
+	/*
+	 * Write data into the FIFO until it is full, which is
+	 * defined as insufficient buffer space to hold a the
+	 * maximum atomic pipe write size.
+	 */
+	while (write(wfd, buf, pipe_buf) != -1) {
+		continue;
+	}
+	ATF_REQUIRE(errno == EAGAIN);
+
+	/* 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);
+
+	/* Read a single byte of data from the FIFO. */
+	ATF_REQUIRE(read(rfd, buf, 1) == 1);
+
+	/*
+	 * 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);
+
+	/*
+	 * Now read all of the data out of the FIFO and ensure that
+	 * we get back to the initial state.
+	 */
+	while (read(rfd, buf, pipe_buf) != -1) {
+		continue;
+	}
+	ATF_REQUIRE(errno == EAGAIN);
+
+	ATF_REQUIRE(poll(pfd, 2, 0) == 1);
+	ATF_REQUIRE(pfd[0].revents == 0);
+	ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
+
+	(void)close(wfd);
+	(void)close(rfd);
+}
+
+ATF_TC_CLEANUP(fifo_inout, tc)
+{
+	(void)unlink(fifo_path);
+}
+
 ATF_TC_WITH_CLEANUP(fifo_hup1);
 ATF_TC_HEAD(fifo_hup1, tc)
 {
@@ -354,6 +453,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, basic);
 	ATF_TP_ADD_TC(tp, err);
 
+	ATF_TP_ADD_TC(tp, fifo_inout);
 	ATF_TP_ADD_TC(tp, fifo_hup1);
 	ATF_TP_ADD_TC(tp, fifo_hup2);
 

Reply via email to