xref: /openbsd/regress/lib/libc/sys/t_pollts.c (revision abbaa274)
1*abbaa274Smbuhl /*	$OpenBSD: t_pollts.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $	*/
2*abbaa274Smbuhl /*	$NetBSD: t_pollts.c,v 1.1 2020/07/17 15:34:17 kamil Exp $	*/
3*abbaa274Smbuhl 
4*abbaa274Smbuhl /*-
5*abbaa274Smbuhl  * Copyright (c) 2011, 2020 The NetBSD Foundation, Inc.
6*abbaa274Smbuhl  * All rights reserved.
7*abbaa274Smbuhl  *
8*abbaa274Smbuhl  * This code is derived from software contributed to The NetBSD Foundation
9*abbaa274Smbuhl  * by Matthias Scheler.
10*abbaa274Smbuhl  *
11*abbaa274Smbuhl  * Redistribution and use in source and binary forms, with or without
12*abbaa274Smbuhl  * modification, are permitted provided that the following conditions
13*abbaa274Smbuhl  * are met:
14*abbaa274Smbuhl  * 1. Redistributions of source code must retain the above copyright
15*abbaa274Smbuhl  *    notice, this list of conditions and the following disclaimer.
16*abbaa274Smbuhl  * 2. Redistributions in binary form must reproduce the above copyright
17*abbaa274Smbuhl  *    notice, this list of conditions and the following disclaimer in the
18*abbaa274Smbuhl  *    documentation and/or other materials provided with the distribution.
19*abbaa274Smbuhl  *
20*abbaa274Smbuhl  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21*abbaa274Smbuhl  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22*abbaa274Smbuhl  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23*abbaa274Smbuhl  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24*abbaa274Smbuhl  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25*abbaa274Smbuhl  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26*abbaa274Smbuhl  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27*abbaa274Smbuhl  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*abbaa274Smbuhl  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29*abbaa274Smbuhl  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30*abbaa274Smbuhl  * POSSIBILITY OF SUCH DAMAGE.
31*abbaa274Smbuhl  */
32*abbaa274Smbuhl #include "macros.h"
33*abbaa274Smbuhl 
34*abbaa274Smbuhl #include <sys/time.h>
35*abbaa274Smbuhl #include <sys/wait.h>
36*abbaa274Smbuhl 
37*abbaa274Smbuhl #include "atf-c.h"
38*abbaa274Smbuhl #include <errno.h>
39*abbaa274Smbuhl #include <fcntl.h>
40*abbaa274Smbuhl #include <paths.h>
41*abbaa274Smbuhl #include <poll.h>
42*abbaa274Smbuhl #include <stdio.h>
43*abbaa274Smbuhl #include <signal.h>
44*abbaa274Smbuhl #include <unistd.h>
45*abbaa274Smbuhl 
46*abbaa274Smbuhl #ifndef POLLTS
47*abbaa274Smbuhl #define POLLTS pollts
48*abbaa274Smbuhl #endif
49*abbaa274Smbuhl 
50*abbaa274Smbuhl ATF_TC(basic);
ATF_TC_HEAD(basic,tc)51*abbaa274Smbuhl ATF_TC_HEAD(basic, tc)
52*abbaa274Smbuhl {
53*abbaa274Smbuhl 	atf_tc_set_md_var(tc, "timeout", "10");
54*abbaa274Smbuhl 	atf_tc_set_md_var(tc, "descr",
55*abbaa274Smbuhl 	    "Basis functionality test for ppoll(2)/pollts(2)");
56*abbaa274Smbuhl }
57*abbaa274Smbuhl 
ATF_TC_BODY(basic,tc)58*abbaa274Smbuhl ATF_TC_BODY(basic, tc)
59*abbaa274Smbuhl {
60*abbaa274Smbuhl 	int fds[2];
61*abbaa274Smbuhl 	struct pollfd pfds[2];
62*abbaa274Smbuhl 	struct timespec timeout;
63*abbaa274Smbuhl 	int ret;
64*abbaa274Smbuhl 
65*abbaa274Smbuhl 	ATF_REQUIRE_EQ(pipe(fds), 0);
66*abbaa274Smbuhl 
67*abbaa274Smbuhl 	pfds[0].fd = fds[0];
68*abbaa274Smbuhl 	pfds[0].events = POLLIN;
69*abbaa274Smbuhl 	pfds[1].fd = fds[1];
70*abbaa274Smbuhl 	pfds[1].events = POLLOUT;
71*abbaa274Smbuhl 
72*abbaa274Smbuhl 	/* Use a timeout of 1 second. */
73*abbaa274Smbuhl 	timeout.tv_sec = 1;
74*abbaa274Smbuhl 	timeout.tv_nsec = 0;
75*abbaa274Smbuhl 
76*abbaa274Smbuhl 	/*
77*abbaa274Smbuhl 	 * Check that we get a timeout waiting for data on the read end
78*abbaa274Smbuhl 	 * of our pipe.
79*abbaa274Smbuhl 	 */
80*abbaa274Smbuhl 	pfds[0].revents = -1;
81*abbaa274Smbuhl 	pfds[1].revents = -1;
82*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfds[0], 1, &timeout, NULL), 0,
83*abbaa274Smbuhl 	    "got: %d", ret);
84*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
85*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
86*abbaa274Smbuhl 
87*abbaa274Smbuhl 	/* Check that the write end of the pipe as reported as ready. */
88*abbaa274Smbuhl 	pfds[0].revents = -1;
89*abbaa274Smbuhl 	pfds[1].revents = -1;
90*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfds[1], 1, &timeout, NULL), 1,
91*abbaa274Smbuhl 	    "got: %d", ret);
92*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
93*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
94*abbaa274Smbuhl 	    pfds[1].revents);
95*abbaa274Smbuhl 
96*abbaa274Smbuhl 	/* Check that only the write end of the pipe as reported as ready. */
97*abbaa274Smbuhl 	pfds[0].revents = -1;
98*abbaa274Smbuhl 	pfds[1].revents = -1;
99*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(ret = POLLTS(pfds, 2, &timeout, NULL), 1,
100*abbaa274Smbuhl 	    "got: %d", ret);
101*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
102*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
103*abbaa274Smbuhl 	    pfds[1].revents);
104*abbaa274Smbuhl 
105*abbaa274Smbuhl 	/* Write data to our pipe. */
106*abbaa274Smbuhl 	ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
107*abbaa274Smbuhl 
108*abbaa274Smbuhl 	/* Check that both ends of our pipe are reported as ready. */
109*abbaa274Smbuhl 	pfds[0].revents = -1;
110*abbaa274Smbuhl 	pfds[1].revents = -1;
111*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(ret = POLLTS(pfds, 2, &timeout, NULL), 2,
112*abbaa274Smbuhl 	    "got: %d", ret);
113*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
114*abbaa274Smbuhl 	    pfds[0].revents);
115*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
116*abbaa274Smbuhl 	    pfds[1].revents);
117*abbaa274Smbuhl 
118*abbaa274Smbuhl 	ATF_REQUIRE_EQ(close(fds[0]), 0);
119*abbaa274Smbuhl 	ATF_REQUIRE_EQ(close(fds[1]), 0);
120*abbaa274Smbuhl }
121*abbaa274Smbuhl 
122*abbaa274Smbuhl ATF_TC(err);
ATF_TC_HEAD(err,tc)123*abbaa274Smbuhl ATF_TC_HEAD(err, tc)
124*abbaa274Smbuhl {
125*abbaa274Smbuhl 	atf_tc_set_md_var(tc, "descr", "Check errors from ppoll(2)/pollts(2)");
126*abbaa274Smbuhl }
127*abbaa274Smbuhl 
ATF_TC_BODY(err,tc)128*abbaa274Smbuhl ATF_TC_BODY(err, tc)
129*abbaa274Smbuhl {
130*abbaa274Smbuhl 	struct timespec timeout;
131*abbaa274Smbuhl 	struct pollfd pfd;
132*abbaa274Smbuhl 	int fd = 0;
133*abbaa274Smbuhl 
134*abbaa274Smbuhl 	pfd.fd = fd;
135*abbaa274Smbuhl 	pfd.events = POLLIN;
136*abbaa274Smbuhl 
137*abbaa274Smbuhl 	timeout.tv_sec = 1;
138*abbaa274Smbuhl 	timeout.tv_nsec = 0;
139*abbaa274Smbuhl 
140*abbaa274Smbuhl 	errno = 0;
141*abbaa274Smbuhl 	ATF_REQUIRE_ERRNO(EFAULT, POLLTS((void *)-1, 1, &timeout, NULL) == -1);
142*abbaa274Smbuhl 
143*abbaa274Smbuhl 	timeout.tv_sec = -1;
144*abbaa274Smbuhl 	timeout.tv_nsec = -1;
145*abbaa274Smbuhl 
146*abbaa274Smbuhl 	errno = 0;
147*abbaa274Smbuhl 	ATF_REQUIRE_ERRNO(EINVAL, POLLTS(&pfd, 1, &timeout, NULL) == -1);
148*abbaa274Smbuhl }
149*abbaa274Smbuhl 
150*abbaa274Smbuhl ATF_TC(sigmask);
ATF_TC_HEAD(sigmask,tc)151*abbaa274Smbuhl ATF_TC_HEAD(sigmask, tc)
152*abbaa274Smbuhl {
153*abbaa274Smbuhl 	atf_tc_set_md_var(tc, "timeout", "10");
154*abbaa274Smbuhl 	atf_tc_set_md_var(tc, "descr",
155*abbaa274Smbuhl 	    "Check that ppoll(2)/pollts(2) restores the signal mask (PR kern/44986)");
156*abbaa274Smbuhl }
157*abbaa274Smbuhl 
ATF_TC_BODY(sigmask,tc)158*abbaa274Smbuhl ATF_TC_BODY(sigmask, tc)
159*abbaa274Smbuhl {
160*abbaa274Smbuhl 	int fd;
161*abbaa274Smbuhl 	struct pollfd pfd;
162*abbaa274Smbuhl 	struct timespec timeout;
163*abbaa274Smbuhl 	sigset_t mask;
164*abbaa274Smbuhl 	int ret;
165*abbaa274Smbuhl 
166*abbaa274Smbuhl 	fd = open(_PATH_DEVNULL, O_RDONLY);
167*abbaa274Smbuhl 	ATF_REQUIRE(fd >= 0);
168*abbaa274Smbuhl 
169*abbaa274Smbuhl 	pfd.fd = fd;
170*abbaa274Smbuhl 	pfd.events = POLLIN;
171*abbaa274Smbuhl 
172*abbaa274Smbuhl 	/* Use a timeout of 1 second. */
173*abbaa274Smbuhl 	timeout.tv_sec = 1;
174*abbaa274Smbuhl 	timeout.tv_nsec = 0;
175*abbaa274Smbuhl 
176*abbaa274Smbuhl 	/* Unblock all signals. */
177*abbaa274Smbuhl 	ATF_REQUIRE_EQ(sigfillset(&mask), 0);
178*abbaa274Smbuhl 	ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0);
179*abbaa274Smbuhl 
180*abbaa274Smbuhl 	/*
181*abbaa274Smbuhl 	 * Check that ppoll(2)/pollts(2) immediately returns. We block *all*
182*abbaa274Smbuhl 	 * signals during ppoll(2)/pollts(2).
183*abbaa274Smbuhl 	 */
184*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfd, 1, &timeout, &mask), 1,
185*abbaa274Smbuhl 	    "got: %d", ret);
186*abbaa274Smbuhl 
187*abbaa274Smbuhl 	/* Check that signals are now longer blocked. */
188*abbaa274Smbuhl 	ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0);
189*abbaa274Smbuhl 	ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0,
190*abbaa274Smbuhl 	    "signal mask was changed.");
191*abbaa274Smbuhl 
192*abbaa274Smbuhl 	ATF_REQUIRE_EQ(close(fd), 0);
193*abbaa274Smbuhl }
194*abbaa274Smbuhl 
ATF_TP_ADD_TCS(tp)195*abbaa274Smbuhl ATF_TP_ADD_TCS(tp)
196*abbaa274Smbuhl {
197*abbaa274Smbuhl 
198*abbaa274Smbuhl 	ATF_TP_ADD_TC(tp, basic);
199*abbaa274Smbuhl 	ATF_TP_ADD_TC(tp, err);
200*abbaa274Smbuhl 	ATF_TP_ADD_TC(tp, sigmask);
201*abbaa274Smbuhl 
202*abbaa274Smbuhl 	return atf_no_error();
203*abbaa274Smbuhl }
204