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);