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