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