Home | History | Annotate | Line # | Download | only in sys
t_poll.c revision 1.3.34.2
      1 /*	$NetBSD: t_poll.c,v 1.3.34.2 2021/10/04 14:32:38 martin Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2011 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Matthias Scheler.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/stat.h>
     33 #include <sys/time.h>
     34 #include <sys/wait.h>
     35 
     36 #include <atf-c.h>
     37 #include <errno.h>
     38 #include <fcntl.h>
     39 #include <paths.h>
     40 #include <poll.h>
     41 #include <stdio.h>
     42 #include <stdlib.h>
     43 #include <signal.h>
     44 #include <unistd.h>
     45 
     46 static int desc;
     47 
     48 static void
     49 child1(void)
     50 {
     51 	struct pollfd pfd;
     52 
     53 	pfd.fd = desc;
     54 	pfd.events = POLLIN | POLLHUP | POLLOUT;
     55 
     56 	(void)poll(&pfd, 1, 2000);
     57 	(void)printf("child1 exit\n");
     58 }
     59 
     60 static void
     61 child2(void)
     62 {
     63 	struct pollfd pfd;
     64 
     65 	pfd.fd = desc;
     66 	pfd.events = POLLIN | POLLHUP | POLLOUT;
     67 
     68 	(void)sleep(1);
     69 	(void)poll(&pfd, 1, INFTIM);
     70 	(void)printf("child2 exit\n");
     71 }
     72 
     73 static void
     74 child3(void)
     75 {
     76 	struct pollfd pfd;
     77 
     78 	(void)sleep(5);
     79 
     80 	pfd.fd = desc;
     81 	pfd.events = POLLIN | POLLHUP | POLLOUT;
     82 
     83 	(void)poll(&pfd, 1, INFTIM);
     84 	(void)printf("child3 exit\n");
     85 }
     86 
     87 ATF_TC(poll_3way);
     88 ATF_TC_HEAD(poll_3way, tc)
     89 {
     90 	atf_tc_set_md_var(tc, "timeout", "15");
     91 	atf_tc_set_md_var(tc, "descr",
     92 	    "Check for 3-way collision for descriptor. First child comes "
     93 	    "and polls on descriptor, second child comes and polls, first "
     94 	    "child times out and exits, third child comes and polls. When "
     95 	    "the wakeup event happens, the two remaining children should "
     96 	    "both be awaken. (kern/17517)");
     97 }
     98 
     99 ATF_TC_BODY(poll_3way, tc)
    100 {
    101 	int pf[2];
    102 	int status, i;
    103 	pid_t pid;
    104 
    105 	pipe(pf);
    106 	desc = pf[0];
    107 
    108 	pid = fork();
    109 	ATF_REQUIRE(pid >= 0);
    110 
    111 	if (pid == 0) {
    112 		(void)close(pf[1]);
    113 		child1();
    114 		_exit(0);
    115 		/* NOTREACHED */
    116 	}
    117 
    118 	pid = fork();
    119 	ATF_REQUIRE(pid >= 0);
    120 
    121 	if (pid == 0) {
    122 		(void)close(pf[1]);
    123 		child2();
    124 		_exit(0);
    125 		/* NOTREACHED */
    126 	}
    127 
    128 	pid = fork();
    129 	ATF_REQUIRE( pid >= 0);
    130 
    131 	if (pid == 0) {
    132 		(void)close(pf[1]);
    133 		child3();
    134 		_exit(0);
    135 		/* NOTREACHED */
    136 	}
    137 
    138 	(void)sleep(10);
    139 
    140 	(void)printf("parent write\n");
    141 
    142 	ATF_REQUIRE(write(pf[1], "konec\n", 6) == 6);
    143 
    144 	for(i = 0; i < 3; ++i)
    145 		(void)wait(&status);
    146 
    147 	(void)printf("parent terminated\n");
    148 }
    149 
    150 ATF_TC(poll_basic);
    151 ATF_TC_HEAD(poll_basic, tc)
    152 {
    153 	atf_tc_set_md_var(tc, "timeout", "10");
    154 	atf_tc_set_md_var(tc, "descr",
    155 	    "Basis functionality test for poll(2)");
    156 }
    157 
    158 ATF_TC_BODY(poll_basic, tc)
    159 {
    160 	int fds[2];
    161 	struct pollfd pfds[2];
    162 	int ret;
    163 
    164 	ATF_REQUIRE_EQ(pipe(fds), 0);
    165 
    166 	pfds[0].fd = fds[0];
    167 	pfds[0].events = POLLIN;
    168 	pfds[1].fd = fds[1];
    169 	pfds[1].events = POLLOUT;
    170 
    171 	/*
    172 	 * Check that we get a timeout waiting for data on the read end
    173 	 * of our pipe.
    174 	 */
    175 	pfds[0].revents = -1;
    176 	pfds[1].revents = -1;
    177 	ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0,
    178 	    "got: %d", ret);
    179 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
    180 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
    181 
    182 	/* Check that the write end of the pipe as reported as ready. */
    183 	pfds[0].revents = -1;
    184 	pfds[1].revents = -1;
    185 	ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1,
    186 	    "got: %d", ret);
    187 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
    188 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
    189 	    pfds[1].revents);
    190 
    191 	/* Check that only the write end of the pipe as reported as ready. */
    192 	pfds[0].revents = -1;
    193 	pfds[1].revents = -1;
    194 	ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1,
    195 	    "got: %d", ret);
    196 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
    197 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
    198 	    pfds[1].revents);
    199 
    200 	/* Write data to our pipe. */
    201 	ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
    202 
    203 	/* Check that both ends of our pipe are reported as ready. */
    204 	pfds[0].revents = -1;
    205 	pfds[1].revents = -1;
    206 	ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2,
    207 	    "got: %d", ret);
    208 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
    209 	    pfds[0].revents);
    210 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
    211 	    pfds[1].revents);
    212 
    213 	ATF_REQUIRE_EQ(close(fds[0]), 0);
    214 	ATF_REQUIRE_EQ(close(fds[1]), 0);
    215 }
    216 
    217 ATF_TC(poll_err);
    218 ATF_TC_HEAD(poll_err, tc)
    219 {
    220 	atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)");
    221 }
    222 
    223 ATF_TC_BODY(poll_err, tc)
    224 {
    225 	struct pollfd pfd;
    226 	int fd = 0;
    227 
    228 	pfd.fd = fd;
    229 	pfd.events = POLLIN;
    230 
    231 	errno = 0;
    232 	ATF_REQUIRE_ERRNO(EFAULT, poll((struct pollfd *)-1, 1, -1) == -1);
    233 
    234 	errno = 0;
    235 	ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1);
    236 }
    237 
    238 ATF_TC(pollts_basic);
    239 ATF_TC_HEAD(pollts_basic, tc)
    240 {
    241 	atf_tc_set_md_var(tc, "timeout", "10");
    242 	atf_tc_set_md_var(tc, "descr",
    243 	    "Basis functionality test for pollts(2)");
    244 }
    245 
    246 ATF_TC_BODY(pollts_basic, tc)
    247 {
    248 	int fds[2];
    249 	struct pollfd pfds[2];
    250 	struct timespec timeout;
    251 	int ret;
    252 
    253 	ATF_REQUIRE_EQ(pipe(fds), 0);
    254 
    255 	pfds[0].fd = fds[0];
    256 	pfds[0].events = POLLIN;
    257 	pfds[1].fd = fds[1];
    258 	pfds[1].events = POLLOUT;
    259 
    260 	/* Use a timeout of 1 second. */
    261 	timeout.tv_sec = 1;
    262 	timeout.tv_nsec = 0;
    263 
    264 	/*
    265 	 * Check that we get a timeout waiting for data on the read end
    266 	 * of our pipe.
    267 	 */
    268 	pfds[0].revents = -1;
    269 	pfds[1].revents = -1;
    270 	ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0,
    271 	    "got: %d", ret);
    272 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
    273 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
    274 
    275 	/* Check that the write end of the pipe as reported as ready. */
    276 	pfds[0].revents = -1;
    277 	pfds[1].revents = -1;
    278 	ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1,
    279 	    "got: %d", ret);
    280 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
    281 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
    282 	    pfds[1].revents);
    283 
    284 	/* Check that only the write end of the pipe as reported as ready. */
    285 	pfds[0].revents = -1;
    286 	pfds[1].revents = -1;
    287 	ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1,
    288 	    "got: %d", ret);
    289 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
    290 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
    291 	    pfds[1].revents);
    292 
    293 	/* Write data to our pipe. */
    294 	ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
    295 
    296 	/* Check that both ends of our pipe are reported as ready. */
    297 	pfds[0].revents = -1;
    298 	pfds[1].revents = -1;
    299 	ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2,
    300 	    "got: %d", ret);
    301 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
    302 	    pfds[0].revents);
    303 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
    304 	    pfds[1].revents);
    305 
    306 	ATF_REQUIRE_EQ(close(fds[0]), 0);
    307 	ATF_REQUIRE_EQ(close(fds[1]), 0);
    308 }
    309 
    310 ATF_TC(pollts_err);
    311 ATF_TC_HEAD(pollts_err, tc)
    312 {
    313 	atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)");
    314 }
    315 
    316 ATF_TC_BODY(pollts_err, tc)
    317 {
    318 	struct timespec timeout;
    319 	struct pollfd pfd;
    320 	int fd = 0;
    321 
    322 	pfd.fd = fd;
    323 	pfd.events = POLLIN;
    324 
    325 	timeout.tv_sec = 1;
    326 	timeout.tv_nsec = 0;
    327 
    328 	errno = 0;
    329 	ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1);
    330 
    331 	timeout.tv_sec = -1;
    332 	timeout.tv_nsec = -1;
    333 
    334 	errno = 0;
    335 	ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1);
    336 }
    337 
    338 ATF_TC(pollts_sigmask);
    339 ATF_TC_HEAD(pollts_sigmask, tc)
    340 {
    341 	atf_tc_set_md_var(tc, "timeout", "10");
    342 	atf_tc_set_md_var(tc, "descr",
    343 	    "Check that pollts(2) restores the signal mask (PR kern/44986)");
    344 }
    345 
    346 ATF_TC_BODY(pollts_sigmask, tc)
    347 {
    348 	int fd;
    349 	struct pollfd pfd;
    350 	struct timespec timeout;
    351 	sigset_t mask;
    352 	int ret;
    353 
    354 	fd = open(_PATH_DEVNULL, O_RDONLY);
    355 	ATF_REQUIRE(fd >= 0);
    356 
    357 	pfd.fd = fd;
    358 	pfd.events = POLLIN;
    359 
    360 	/* Use a timeout of 1 second. */
    361 	timeout.tv_sec = 1;
    362 	timeout.tv_nsec = 0;
    363 
    364 	/* Unblock all signals. */
    365 	ATF_REQUIRE_EQ(sigfillset(&mask), 0);
    366 	ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0);
    367 
    368 	/*
    369 	 * Check that pollts(2) immediately returns. We block *all*
    370 	 * signals during pollts(2).
    371 	 */
    372 	ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1,
    373 	    "got: %d", ret);
    374 
    375 	/* Check that signals are now longer blocked. */
    376 	ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0);
    377 	ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0,
    378 	    "signal mask was changed.");
    379 
    380 	ATF_REQUIRE_EQ(close(fd), 0);
    381 }
    382 
    383 static const char	fifo_path[] = "pollhup_fifo";
    384 
    385 static void
    386 fifo_support(void)
    387 {
    388 	errno = 0;
    389 	if (mkfifo(fifo_path, 0600) == 0) {
    390 		ATF_REQUIRE(unlink(fifo_path) == 0);
    391 		return;
    392 	}
    393 
    394 	if (errno == EOPNOTSUPP) {
    395 		atf_tc_skip("the kernel does not support FIFOs");
    396 	} else {
    397 		atf_tc_fail("mkfifo(2) failed");
    398 	}
    399 }
    400 
    401 ATF_TC_WITH_CLEANUP(fifo_inout);
    402 ATF_TC_HEAD(fifo_inout, tc)
    403 {
    404 	atf_tc_set_md_var(tc, "descr",
    405 	    "Check POLLIN/POLLOUT behavior with fifos");
    406 }
    407 
    408 ATF_TC_BODY(fifo_inout, tc)
    409 {
    410 	struct pollfd pfd[2];
    411 	char *buf;
    412 	int rfd, wfd;
    413 	long pipe_buf;
    414 
    415 	fifo_support();
    416 
    417 	ATF_REQUIRE(mkfifo(fifo_path, 0600) == 0);
    418 	ATF_REQUIRE((rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)) >= 0);
    419 	ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY | O_NONBLOCK)) >= 0);
    420 
    421 	/* Get the maximum atomic pipe write size. */
    422 	pipe_buf = fpathconf(wfd, _PC_PIPE_BUF);
    423 	ATF_REQUIRE(pipe_buf > 1);
    424 
    425 	buf = malloc(pipe_buf);
    426 	ATF_REQUIRE(buf != NULL);
    427 
    428 	memset(&pfd, 0, sizeof(pfd));
    429 	pfd[0].fd = rfd;
    430 	pfd[0].events = POLLIN | POLLRDNORM;
    431 	pfd[1].fd = wfd;
    432 	pfd[1].events = POLLOUT | POLLWRNORM;
    433 
    434 	/* We expect the FIFO to be writable but not readable. */
    435 	ATF_REQUIRE(poll(pfd, 2, 0) == 1);
    436 	ATF_REQUIRE(pfd[0].revents == 0);
    437 	ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
    438 
    439 	/* Write a single byte of data into the FIFO. */
    440 	ATF_REQUIRE(write(wfd, buf, 1) == 1);
    441 
    442 	/* We expect the FIFO to be readable and writable. */
    443 	ATF_REQUIRE(poll(pfd, 2, 0) == 2);
    444 	ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM));
    445 	ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
    446 
    447 	/* Read that single byte back out. */
    448 	ATF_REQUIRE(read(rfd, buf, 1) == 1);
    449 
    450 	/*
    451 	 * Write data into the FIFO until it is full, which is
    452 	 * defined as insufficient buffer space to hold a the
    453 	 * maximum atomic pipe write size.
    454 	 */
    455 	while (write(wfd, buf, pipe_buf) != -1) {
    456 		continue;
    457 	}
    458 	ATF_REQUIRE(errno == EAGAIN);
    459 
    460 	/* We expect the FIFO to be readble but not writable. */
    461 	ATF_REQUIRE(poll(pfd, 2, 0) == 1);
    462 	ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM));
    463 	ATF_REQUIRE(pfd[1].revents == 0);
    464 
    465 	/* Read a single byte of data from the FIFO. */
    466 	ATF_REQUIRE(read(rfd, buf, 1) == 1);
    467 
    468 	/*
    469 	 * Because we have read only a single byte out, there will
    470 	 * be insufficient space for a pipe_buf-sized message, so
    471 	 * the FIFO should still not be writable.
    472 	 */
    473 	ATF_REQUIRE(poll(pfd, 2, 0) == 1);
    474 	ATF_REQUIRE(pfd[0].revents == (POLLIN | POLLRDNORM));
    475 	ATF_REQUIRE(pfd[1].revents == 0);
    476 
    477 	/*
    478 	 * Now read enough so that exactly pipe_buf space should
    479 	 * be available.  The FIFO should be writable after that.
    480 	 * N.B. we don't care if it's readable at this point.
    481 	 */
    482 	ATF_REQUIRE(read(rfd, buf, pipe_buf - 1) == pipe_buf - 1);
    483 	ATF_REQUIRE(poll(pfd, 2, 0) >= 1);
    484 	ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
    485 
    486 	/*
    487 	 * Now read all of the data out of the FIFO and ensure that
    488 	 * we get back to the initial state.
    489 	 */
    490 	while (read(rfd, buf, pipe_buf) != -1) {
    491 		continue;
    492 	}
    493 	ATF_REQUIRE(errno == EAGAIN);
    494 
    495 	ATF_REQUIRE(poll(pfd, 2, 0) == 1);
    496 	ATF_REQUIRE(pfd[0].revents == 0);
    497 	ATF_REQUIRE(pfd[1].revents == (POLLOUT | POLLWRNORM));
    498 
    499 	(void)close(wfd);
    500 	(void)close(rfd);
    501 }
    502 
    503 ATF_TC_CLEANUP(fifo_inout, tc)
    504 {
    505 	(void)unlink(fifo_path);
    506 }
    507 
    508 ATF_TC_WITH_CLEANUP(fifo_hup1);
    509 ATF_TC_HEAD(fifo_hup1, tc)
    510 {
    511 	atf_tc_set_md_var(tc, "descr",
    512 	    "Check POLLHUP behavior with fifos [1]");
    513 }
    514 
    515 ATF_TC_BODY(fifo_hup1, tc)
    516 {
    517 	struct pollfd pfd;
    518 	int rfd, wfd;
    519 
    520 	fifo_support();
    521 
    522 	ATF_REQUIRE(mkfifo(fifo_path, 0600) == 0);
    523 	ATF_REQUIRE((rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)) >= 0);
    524 	ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY)) >= 0);
    525 
    526 	memset(&pfd, 0, sizeof(pfd));
    527 	pfd.fd = rfd;
    528 	pfd.events = POLLIN;
    529 
    530 	(void)close(wfd);
    531 
    532 	ATF_REQUIRE(poll(&pfd, 1, 0) == 1);
    533 	ATF_REQUIRE((pfd.revents & POLLHUP) != 0);
    534 
    535 	/*
    536 	 * Check that POLLHUP is cleared when a writer re-connects.
    537 	 * Since the writer will not put any data into the FIFO, we
    538 	 * expect no events.
    539 	 */
    540 	memset(&pfd, 0, sizeof(pfd));
    541 	pfd.fd = rfd;
    542 	pfd.events = POLLIN;
    543 
    544 	ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY)) >= 0);
    545 	ATF_REQUIRE(poll(&pfd, 1, 0) == 0);
    546 }
    547 
    548 ATF_TC_CLEANUP(fifo_hup1, tc)
    549 {
    550 	(void)unlink(fifo_path);
    551 }
    552 
    553 ATF_TC_WITH_CLEANUP(fifo_hup2);
    554 ATF_TC_HEAD(fifo_hup2, tc)
    555 {
    556 	atf_tc_set_md_var(tc, "descr",
    557 	    "Check POLLHUP behavior with fifos [2]");
    558 }
    559 
    560 ATF_TC_BODY(fifo_hup2, tc)
    561 {
    562 	struct pollfd pfd;
    563 	int rfd, wfd;
    564 	pid_t pid;
    565 	struct timespec ts1, ts2;
    566 
    567 	fifo_support();
    568 
    569 	ATF_REQUIRE(mkfifo(fifo_path, 0600) == 0);
    570 	ATF_REQUIRE((rfd = open(fifo_path, O_RDONLY | O_NONBLOCK)) >= 0);
    571 	ATF_REQUIRE((wfd = open(fifo_path, O_WRONLY)) >= 0);
    572 
    573 	memset(&pfd, 0, sizeof(pfd));
    574 	pfd.fd = rfd;
    575 	pfd.events = POLLIN;
    576 
    577 	pid = fork();
    578 	ATF_REQUIRE(pid >= 0);
    579 
    580 	if (pid == 0) {
    581 		(void)close(rfd);
    582 		sleep(5);
    583 		(void)close(wfd);
    584 		_exit(0);
    585 	}
    586 	(void)close(wfd);
    587 
    588 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts1) == 0);
    589 	ATF_REQUIRE(poll(&pfd, 1, INFTIM) == 1);
    590 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts2) == 0);
    591 
    592 	/* Make sure at least a couple of seconds have elapsed. */
    593 	ATF_REQUIRE(ts2.tv_sec - ts1.tv_sec >= 2);
    594 
    595 	ATF_REQUIRE((pfd.revents & POLLHUP) != 0);
    596 }
    597 
    598 ATF_TC_CLEANUP(fifo_hup2, tc)
    599 {
    600 	(void)unlink(fifo_path);
    601 }
    602 
    603 ATF_TP_ADD_TCS(tp)
    604 {
    605 
    606 	ATF_TP_ADD_TC(tp, poll_3way);
    607 	ATF_TP_ADD_TC(tp, poll_basic);
    608 	ATF_TP_ADD_TC(tp, poll_err);
    609 	ATF_TP_ADD_TC(tp, pollts_basic);
    610 	ATF_TP_ADD_TC(tp, pollts_err);
    611 	ATF_TP_ADD_TC(tp, pollts_sigmask);
    612 
    613 	ATF_TP_ADD_TC(tp, fifo_inout);
    614 	ATF_TP_ADD_TC(tp, fifo_hup1);
    615 	ATF_TP_ADD_TC(tp, fifo_hup2);
    616 
    617 	return atf_no_error();
    618 }
    619