1 /* $NetBSD: t_poll.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */
4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
52 pfd
.events
= POLLIN
| POLLHUP
| POLLOUT
;
54 (void)poll(&pfd
, 1, 2000);
55 (void)printf("child1 exit\n");
64 pfd
.events
= POLLIN
| POLLHUP
| POLLOUT
;
67 (void)poll(&pfd
, 1, INFTIM
);
68 (void)printf("child2 exit\n");
79 pfd
.events
= POLLIN
| POLLHUP
| POLLOUT
;
81 (void)poll(&pfd
, 1, INFTIM
);
82 (void)printf("child3 exit\n");
86 ATF_TC_HEAD(poll_3way
, tc
)
88 atf_tc_set_md_var(tc
, "timeout", "15");
89 atf_tc_set_md_var(tc
, "descr",
90 "Check for 3-way collision for descriptor. First child comes "
91 "and polls on descriptor, second child comes and polls, first "
92 "child times out and exits, third child comes and polls. When "
93 "the wakeup event happens, the two remaining children should "
94 "both be awaken. (kern/17517)");
97 ATF_TC_BODY(poll_3way
, tc
)
107 ATF_REQUIRE(pid
>= 0);
117 ATF_REQUIRE(pid
>= 0);
127 ATF_REQUIRE( pid
>= 0);
138 (void)printf("parent write\n");
140 ATF_REQUIRE(write(pf
[1], "konec\n", 6) == 6);
142 for(i
= 0; i
< 3; ++i
)
145 (void)printf("parent terminated\n");
149 ATF_TC_HEAD(poll_basic
, tc
)
151 atf_tc_set_md_var(tc
, "timeout", "10");
152 atf_tc_set_md_var(tc
, "descr",
153 "Basis functionality test for poll(2)");
156 ATF_TC_BODY(poll_basic
, tc
)
159 struct pollfd pfds
[2];
162 ATF_REQUIRE_EQ(pipe(fds
), 0);
165 pfds
[0].events
= POLLIN
;
167 pfds
[1].events
= POLLOUT
;
170 * Check that we get a timeout waiting for data on the read end
173 pfds
[0].revents
= -1;
174 pfds
[1].revents
= -1;
175 ATF_REQUIRE_EQ_MSG(ret
= poll(&pfds
[0], 1, 1), 0,
177 ATF_REQUIRE_EQ_MSG(pfds
[0].revents
, 0, "got: %d", pfds
[0].revents
);
178 ATF_REQUIRE_EQ_MSG(pfds
[1].revents
, -1, "got: %d", pfds
[1].revents
);
180 /* Check that the write end of the pipe as reported as ready. */
181 pfds
[0].revents
= -1;
182 pfds
[1].revents
= -1;
183 ATF_REQUIRE_EQ_MSG(ret
= poll(&pfds
[1], 1, 1), 1,
185 ATF_REQUIRE_EQ_MSG(pfds
[0].revents
, -1, "got: %d", pfds
[0].revents
);
186 ATF_REQUIRE_EQ_MSG(pfds
[1].revents
, POLLOUT
, "got: %d",\
189 /* Check that only the write end of the pipe as reported as ready. */
190 pfds
[0].revents
= -1;
191 pfds
[1].revents
= -1;
192 ATF_REQUIRE_EQ_MSG(ret
= poll(pfds
, 2, 1), 1,
194 ATF_REQUIRE_EQ_MSG(pfds
[0].revents
, 0, "got: %d", pfds
[0].revents
);
195 ATF_REQUIRE_EQ_MSG(pfds
[1].revents
, POLLOUT
, "got: %d",
198 /* Write data to our pipe. */
199 ATF_REQUIRE_EQ(write(fds
[1], "", 1), 1);
201 /* Check that both ends of our pipe are reported as ready. */
202 pfds
[0].revents
= -1;
203 pfds
[1].revents
= -1;
204 ATF_REQUIRE_EQ_MSG(ret
= poll(pfds
, 2, 1), 2,
206 ATF_REQUIRE_EQ_MSG(pfds
[0].revents
, POLLIN
, "got: %d",
208 ATF_REQUIRE_EQ_MSG(pfds
[1].revents
, POLLOUT
, "got: %d",
211 ATF_REQUIRE_EQ(close(fds
[0]), 0);
212 ATF_REQUIRE_EQ(close(fds
[1]), 0);
216 ATF_TC_HEAD(poll_err
, tc
)
218 atf_tc_set_md_var(tc
, "descr", "Check errors from poll(2)");
221 ATF_TC_BODY(poll_err
, tc
)
230 ATF_REQUIRE_ERRNO(EFAULT
, poll((struct pollfd
*)-1, 1, -1) == -1);
233 ATF_REQUIRE_ERRNO(EINVAL
, poll(&pfd
, 1, -2) == -1);
236 ATF_TC(pollts_basic
);
237 ATF_TC_HEAD(pollts_basic
, tc
)
239 atf_tc_set_md_var(tc
, "timeout", "10");
240 atf_tc_set_md_var(tc
, "descr",
241 "Basis functionality test for pollts(2)");
244 ATF_TC_BODY(pollts_basic
, tc
)
247 struct pollfd pfds
[2];
248 struct timespec timeout
;
251 ATF_REQUIRE_EQ(pipe(fds
), 0);
254 pfds
[0].events
= POLLIN
;
256 pfds
[1].events
= POLLOUT
;
258 /* Use a timeout of 1 second. */
263 * Check that we get a timeout waiting for data on the read end
266 pfds
[0].revents
= -1;
267 pfds
[1].revents
= -1;
268 ATF_REQUIRE_EQ_MSG(ret
= pollts(&pfds
[0], 1, &timeout
, NULL
), 0,
270 ATF_REQUIRE_EQ_MSG(pfds
[0].revents
, 0, "got: %d", pfds
[0].revents
);
271 ATF_REQUIRE_EQ_MSG(pfds
[1].revents
, -1, "got: %d", pfds
[1].revents
);
273 /* Check that the write end of the pipe as reported as ready. */
274 pfds
[0].revents
= -1;
275 pfds
[1].revents
= -1;
276 ATF_REQUIRE_EQ_MSG(ret
= pollts(&pfds
[1], 1, &timeout
, NULL
), 1,
278 ATF_REQUIRE_EQ_MSG(pfds
[0].revents
, -1, "got: %d", pfds
[0].revents
);
279 ATF_REQUIRE_EQ_MSG(pfds
[1].revents
, POLLOUT
, "got: %d",\
282 /* Check that only the write end of the pipe as reported as ready. */
283 pfds
[0].revents
= -1;
284 pfds
[1].revents
= -1;
285 ATF_REQUIRE_EQ_MSG(ret
= pollts(pfds
, 2, &timeout
, NULL
), 1,
287 ATF_REQUIRE_EQ_MSG(pfds
[0].revents
, 0, "got: %d", pfds
[0].revents
);
288 ATF_REQUIRE_EQ_MSG(pfds
[1].revents
, POLLOUT
, "got: %d",
291 /* Write data to our pipe. */
292 ATF_REQUIRE_EQ(write(fds
[1], "", 1), 1);
294 /* Check that both ends of our pipe are reported as ready. */
295 pfds
[0].revents
= -1;
296 pfds
[1].revents
= -1;
297 ATF_REQUIRE_EQ_MSG(ret
= pollts(pfds
, 2, &timeout
, NULL
), 2,
299 ATF_REQUIRE_EQ_MSG(pfds
[0].revents
, POLLIN
, "got: %d",
301 ATF_REQUIRE_EQ_MSG(pfds
[1].revents
, POLLOUT
, "got: %d",
304 ATF_REQUIRE_EQ(close(fds
[0]), 0);
305 ATF_REQUIRE_EQ(close(fds
[1]), 0);
309 ATF_TC_HEAD(pollts_err
, tc
)
311 atf_tc_set_md_var(tc
, "descr", "Check errors from pollts(2)");
314 ATF_TC_BODY(pollts_err
, tc
)
316 struct timespec timeout
;
327 ATF_REQUIRE_ERRNO(EFAULT
, pollts((void *)-1, 1, &timeout
, NULL
) == -1);
330 timeout
.tv_nsec
= -1;
333 ATF_REQUIRE_ERRNO(EINVAL
, pollts(&pfd
, 1, &timeout
, NULL
) == -1);
336 ATF_TC(pollts_sigmask
);
337 ATF_TC_HEAD(pollts_sigmask
, tc
)
339 atf_tc_set_md_var(tc
, "timeout", "10");
340 atf_tc_set_md_var(tc
, "descr",
341 "Check that pollts(2) restores the signal mask (PR kern/44986)");
344 ATF_TC_BODY(pollts_sigmask
, tc
)
348 struct timespec timeout
;
352 fd
= open(_PATH_DEVNULL
, O_RDONLY
);
353 ATF_REQUIRE(fd
>= 0);
358 /* Use a timeout of 1 second. */
362 /* Unblock all signals. */
363 ATF_REQUIRE_EQ(sigfillset(&mask
), 0);
364 ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK
, &mask
, NULL
), 0);
367 * Check that pollts(2) immediately returns. We block *all*
368 * signals during pollts(2).
370 ATF_REQUIRE_EQ_MSG(ret
= pollts(&pfd
, 1, &timeout
, &mask
), 1,
373 /* Check that signals are now longer blocked. */
374 ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK
, NULL
, &mask
), 0);
375 ATF_REQUIRE_EQ_MSG(sigismember(&mask
, SIGUSR1
), 0,
376 "signal mask was changed.");
378 ATF_REQUIRE_EQ(close(fd
), 0);
384 ATF_TP_ADD_TC(tp
, poll_3way
);
385 ATF_TP_ADD_TC(tp
, poll_basic
);
386 ATF_TP_ADD_TC(tp
, poll_err
);
387 ATF_TP_ADD_TC(tp
, pollts_basic
);
388 ATF_TP_ADD_TC(tp
, pollts_err
);
389 ATF_TP_ADD_TC(tp
, pollts_sigmask
);
391 return atf_no_error();