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