xref: /netbsd-src/tests/lib/libc/sys/t_timerfd.c (revision afab4e300d3a9fb07dd8c80daf53d0feb3345706)
1 /* $NetBSD: t_timerfd.c,v 1.4 2022/02/20 15:21:14 thorpej Exp $ */
2 
3 /*-
4  * Copyright (c) 2020 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __COPYRIGHT("@(#) Copyright (c) 2020\
31  The NetBSD Foundation, inc. All rights reserved.");
32 __RCSID("$NetBSD: t_timerfd.c,v 1.4 2022/02/20 15:21:14 thorpej Exp $");
33 
34 #include <sys/types.h>
35 #include <sys/event.h>
36 #include <sys/ioctl.h>
37 #include <sys/select.h>
38 #include <sys/stat.h>
39 #include <sys/syscall.h>
40 #include <sys/timerfd.h>
41 #include <errno.h>
42 #include <poll.h>
43 #include <pthread.h>
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <time.h>
47 #include <unistd.h>
48 
49 #include <atf-c.h>
50 
51 #include "isqemu.h"
52 
53 struct helper_context {
54 	int	fd;
55 
56 	pthread_barrier_t barrier;
57 };
58 
59 static void
60 init_helper_context(struct helper_context * const ctx)
61 {
62 
63 	memset(ctx, 0, sizeof(*ctx));
64 
65 	ATF_REQUIRE(pthread_barrier_init(&ctx->barrier, NULL, 2) == 0);
66 }
67 
68 static bool
69 wait_barrier(struct helper_context * const ctx)
70 {
71 	int rv = pthread_barrier_wait(&ctx->barrier);
72 
73 	return rv == 0 || rv == PTHREAD_BARRIER_SERIAL_THREAD;
74 }
75 
76 static bool
77 check_value_against_bounds(uint64_t value, uint64_t lower, uint64_t upper)
78 {
79 
80 	/*
81 	 * If running under QEMU make sure the upper bound is large
82 	 * enough for the effect of kern/43997
83 	 */
84 	if (isQEMU()) {
85 		upper *= 4;
86 	}
87 
88 	if (value < lower || value > upper) {
89 		printf("val %" PRIu64 " not in [ %" PRIu64 ", %" PRIu64 " ]\n",
90 		    value, lower, upper);
91 	}
92 
93 	return value >= lower && value <= upper;
94 }
95 
96 /*****************************************************************************/
97 
98 static int
99 timerfd_read(int fd, uint64_t *valp)
100 {
101 	uint64_t val;
102 
103 	switch (read(fd, &val, sizeof(val))) {
104 	case -1:
105 		return -1;
106 
107 	case sizeof(val):
108 		*valp = val;
109 		return 0;
110 
111 	default:
112 		/* ?? Should never happen. */
113 		errno = EIO;
114 		return -1;
115 	}
116 }
117 
118 /*****************************************************************************/
119 
120 ATF_TC(timerfd_create);
121 ATF_TC_HEAD(timerfd_create, tc)
122 {
123 	atf_tc_set_md_var(tc, "descr", "validates timerfd_create()");
124 }
125 ATF_TC_BODY(timerfd_create, tc)
126 {
127 	int fd;
128 
129 	ATF_REQUIRE((fd = timerfd_create(CLOCK_REALTIME, 0)) >= 0);
130 	(void) close(fd);
131 
132 	ATF_REQUIRE((fd = timerfd_create(CLOCK_MONOTONIC, 0)) >= 0);
133 	(void) close(fd);
134 
135 	ATF_REQUIRE_ERRNO(EINVAL,
136 	    (fd = timerfd_create(CLOCK_VIRTUAL, 0)) == -1);
137 
138 	ATF_REQUIRE_ERRNO(EINVAL,
139 	    (fd = timerfd_create(CLOCK_PROF, 0)) == -1);
140 
141 	ATF_REQUIRE_ERRNO(EINVAL,
142 	    (fd = timerfd_create(CLOCK_REALTIME,
143 	    			    ~(TFD_CLOEXEC | TFD_NONBLOCK))) == -1);
144 }
145 
146 /*****************************************************************************/
147 
148 ATF_TC(timerfd_bogusfd);
149 ATF_TC_HEAD(timerfd_bogusfd, tc)
150 {
151 	atf_tc_set_md_var(tc, "descr",
152 	    "validates rejection of bogus fds by timerfd_{get,set}time()");
153 }
154 ATF_TC_BODY(timerfd_bogusfd, tc)
155 {
156 	struct itimerspec its = { 0 };
157 	int fd;
158 
159 	ATF_REQUIRE((fd = kqueue()) >= 0);	/* arbitrary fd type */
160 
161 	ATF_REQUIRE_ERRNO(EINVAL,
162 	    timerfd_gettime(fd, &its) == -1);
163 
164 	its.it_value.tv_sec = 5;
165 	ATF_REQUIRE_ERRNO(EINVAL,
166 	    timerfd_settime(fd, 0, &its, NULL) == -1);
167 
168 	(void) close(fd);
169 }
170 
171 /*****************************************************************************/
172 
173 ATF_TC(timerfd_block);
174 ATF_TC_HEAD(timerfd_block, tc)
175 {
176 	atf_tc_set_md_var(tc, "descr", "validates blocking behavior");
177 }
178 ATF_TC_BODY(timerfd_block, tc)
179 {
180 	struct timespec then, now, delta;
181 	uint64_t val;
182 	int fd;
183 
184 	ATF_REQUIRE((fd = timerfd_create(CLOCK_MONOTONIC, 0)) >= 0);
185 
186 	const struct itimerspec its = {
187 		.it_value = { .tv_sec = 1, .tv_nsec = 0 },
188 		.it_interval = { .tv_sec = 0, .tv_nsec = 0 },
189 	};
190 
191 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &then) == 0);
192 	ATF_REQUIRE(timerfd_settime(fd, 0, &its, NULL) == 0);
193 	ATF_REQUIRE(timerfd_read(fd, &val) == 0);
194 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &now) == 0);
195 	ATF_REQUIRE(check_value_against_bounds(val, 1, 1));
196 
197 	timespecsub(&now, &then, &delta);
198 	ATF_REQUIRE(check_value_against_bounds(delta.tv_sec, 1, 1));
199 
200 	(void) close(fd);
201 }
202 
203 /*****************************************************************************/
204 
205 ATF_TC(timerfd_repeating);
206 ATF_TC_HEAD(timerfd_repeating, tc)
207 {
208 	atf_tc_set_md_var(tc, "descr", "validates repeating timer behavior");
209 }
210 ATF_TC_BODY(timerfd_repeating, tc)
211 {
212 	struct timespec then, now, delta;
213 	uint64_t val;
214 	int fd;
215 
216 	ATF_REQUIRE((fd = timerfd_create(CLOCK_MONOTONIC,
217 					    TFD_NONBLOCK)) >= 0);
218 
219 	const struct itimerspec its = {
220 		.it_value = { .tv_sec = 0, .tv_nsec = 200000000 },
221 		.it_interval = { .tv_sec = 0, .tv_nsec = 200000000 },
222 	};
223 
224 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &then) == 0);
225 	ATF_REQUIRE(timerfd_settime(fd, 0, &its, NULL) == 0);
226 	ATF_REQUIRE(sleep(1) == 0);
227 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &now) == 0);
228 	ATF_REQUIRE(timerfd_read(fd, &val) == 0);
229 	/* allow some slop */
230 	ATF_REQUIRE(check_value_against_bounds(val, 3, 5));
231 
232 	timespecsub(&now, &then, &delta);
233 	ATF_REQUIRE(check_value_against_bounds(delta.tv_sec, 1, 1));
234 
235 	(void) close(fd);
236 }
237 
238 /*****************************************************************************/
239 
240 ATF_TC(timerfd_abstime);
241 ATF_TC_HEAD(timerfd_abstime, tc)
242 {
243 	atf_tc_set_md_var(tc, "descr", "validates specifying abstime");
244 }
245 ATF_TC_BODY(timerfd_abstime, tc)
246 {
247 	struct timespec then, now, delta;
248 	uint64_t val;
249 	int fd;
250 
251 	ATF_REQUIRE((fd = timerfd_create(CLOCK_MONOTONIC, 0)) >= 0);
252 
253 	struct itimerspec its = {
254 		.it_value = { .tv_sec = 0, .tv_nsec = 0 },
255 		.it_interval = { .tv_sec = 0, .tv_nsec = 0 },
256 	};
257 
258 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &then) == 0);
259 	its.it_value = then;
260 	its.it_value.tv_sec += 1;
261 	ATF_REQUIRE(timerfd_settime(fd, TFD_TIMER_ABSTIME, &its, NULL) == 0);
262 	ATF_REQUIRE(timerfd_read(fd, &val) == 0);
263 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &now) == 0);
264 	ATF_REQUIRE(check_value_against_bounds(val, 1, 1));
265 
266 	timespecsub(&now, &then, &delta);
267 	ATF_REQUIRE(check_value_against_bounds(delta.tv_sec, 1, 1));
268 
269 	(void) close(fd);
270 }
271 
272 /*****************************************************************************/
273 
274 ATF_TC(timerfd_cancel_on_set_immed);
275 ATF_TC_HEAD(timerfd_cancel_on_set_immed, tc)
276 {
277 	atf_tc_set_md_var(tc, "descr", "validates cancel-on-set - immediate");
278 	atf_tc_set_md_var(tc, "require.user", "root");
279 }
280 ATF_TC_BODY(timerfd_cancel_on_set_immed, tc)
281 {
282 	struct timespec now;
283 	uint64_t val;
284 	int fd;
285 
286 	ATF_REQUIRE((fd = timerfd_create(CLOCK_REALTIME, 0)) >= 0);
287 
288 	const struct itimerspec its = {
289 		.it_value = { .tv_sec = 60 * 60, .tv_nsec = 0 },
290 		.it_interval = { .tv_sec = 0, .tv_nsec = 0 },
291 	};
292 
293 	ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &now) == 0);
294 	ATF_REQUIRE(timerfd_settime(fd, TFD_TIMER_CANCEL_ON_SET,
295 				    &its, NULL) == 0);
296 	ATF_REQUIRE(clock_settime(CLOCK_REALTIME, &now) == 0);
297 	ATF_REQUIRE_ERRNO(ECANCELED, timerfd_read(fd, &val) == -1);
298 
299 	(void) close(fd);
300 }
301 
302 /*****************************************************************************/
303 
304 static void *
305 timerfd_cancel_on_set_block_helper(void * const v)
306 {
307 	struct helper_context * const ctx = v;
308 	struct timespec now;
309 
310 	ATF_REQUIRE(wait_barrier(ctx));
311 
312 	ATF_REQUIRE(sleep(2) == 0);
313 	ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &now) == 0);
314 	ATF_REQUIRE(clock_settime(CLOCK_REALTIME, &now) == 0);
315 
316 	return NULL;
317 }
318 
319 ATF_TC(timerfd_cancel_on_set_block);
320 ATF_TC_HEAD(timerfd_cancel_on_set_block, tc)
321 {
322 	atf_tc_set_md_var(tc, "descr", "validates cancel-on-set - blocking");
323 	atf_tc_set_md_var(tc, "require.user", "root");
324 }
325 ATF_TC_BODY(timerfd_cancel_on_set_block, tc)
326 {
327 	struct helper_context ctx;
328 	pthread_t helper;
329 	void *join_val;
330 	uint64_t val;
331 	int fd;
332 
333 	ATF_REQUIRE((fd = timerfd_create(CLOCK_REALTIME, 0)) >= 0);
334 
335 	const struct itimerspec its = {
336 		.it_value = { .tv_sec = 60 * 60, .tv_nsec = 0 },
337 		.it_interval = { .tv_sec = 0, .tv_nsec = 0 },
338 	};
339 
340 	init_helper_context(&ctx);
341 
342 	ATF_REQUIRE(timerfd_settime(fd, TFD_TIMER_CANCEL_ON_SET,
343 				    &its, NULL) == 0);
344 	ATF_REQUIRE(pthread_create(&helper, NULL,
345 				timerfd_cancel_on_set_block_helper, &ctx) == 0);
346 	ATF_REQUIRE(wait_barrier(&ctx));
347 	ATF_REQUIRE_ERRNO(ECANCELED, timerfd_read(fd, &val) == -1);
348 
349 	ATF_REQUIRE(pthread_join(helper, &join_val) == 0);
350 
351 	(void) close(fd);
352 }
353 
354 /*****************************************************************************/
355 
356 ATF_TC(timerfd_select_poll_kevent_immed);
357 ATF_TC_HEAD(timerfd_select_poll_kevent_immed, tc)
358 {
359 	atf_tc_set_md_var(tc, "descr",
360 	    "validates select/poll/kevent behavior - immediate return");
361 }
362 ATF_TC_BODY(timerfd_select_poll_kevent_immed, tc)
363 {
364 	const struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
365 	struct itimerspec its;
366 	struct timeval tv;
367 	struct stat st;
368 	struct pollfd fds[1];
369 	uint64_t val;
370 	fd_set readfds, writefds, exceptfds;
371 	int fd;
372 	int kq;
373 	struct kevent kev[1];
374 
375 	ATF_REQUIRE((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) >= 0);
376 
377 	ATF_REQUIRE((kq = kqueue()) >= 0);
378 	EV_SET(&kev[0], fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
379 	ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, &ts) == 0);
380 
381 	/*
382 	 * fd should be writable but not readable.  Pass all of the
383 	 * event bits; we should only get back POLLOUT | POLLWRNORM.
384 	 * (It's writable only in so far as we'll get an error if we try.)
385 	 */
386 	fds[0].fd = fd;
387 	fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI |
388 	    POLLOUT | POLLWRNORM | POLLWRBAND | POLLHUP;
389 	fds[0].revents = 0;
390 	ATF_REQUIRE(poll(fds, 1, 0) == 1);
391 	ATF_REQUIRE(fds[0].revents == (POLLOUT | POLLWRNORM));
392 
393 	/*
394 	 * As above; fd should only be set in writefds upon return
395 	 * from the select() call.
396 	 */
397 	FD_ZERO(&readfds);
398 	FD_ZERO(&writefds);
399 	FD_ZERO(&exceptfds);
400 	tv.tv_sec = 0;
401 	tv.tv_usec = 0;
402 	FD_SET(fd, &readfds);
403 	FD_SET(fd, &writefds);
404 	FD_SET(fd, &exceptfds);
405 	ATF_REQUIRE(select(fd + 1, &readfds, &writefds, &exceptfds, &tv) == 1);
406 	ATF_REQUIRE(!FD_ISSET(fd, &readfds));
407 	ATF_REQUIRE(FD_ISSET(fd, &writefds));
408 	ATF_REQUIRE(!FD_ISSET(fd, &exceptfds));
409 
410 	/*
411 	 * Now set a one-shot half-second timer, wait for it to expire, and
412 	 * then check again.
413 	 */
414 	memset(&its, 0, sizeof(its));
415 	its.it_value.tv_sec = 0;
416 	its.it_value.tv_nsec = 500000000;
417 	ATF_REQUIRE(timerfd_settime(fd, 0, &its, NULL) == 0);
418 	ATF_REQUIRE(sleep(2) == 0);
419 
420 	/* Verify it actually fired via the stat() back-channel. */
421 	ATF_REQUIRE(fstat(fd, &st) == 0);
422 	ATF_REQUIRE(st.st_size == 1);
423 
424 	fds[0].fd = fd;
425 	fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI |
426 	    POLLOUT | POLLWRNORM | POLLWRBAND | POLLHUP;
427 	fds[0].revents = 0;
428 	ATF_REQUIRE(poll(fds, 1, 0) == 1);
429 	ATF_REQUIRE(fds[0].revents == (POLLIN | POLLRDNORM |
430 				       POLLOUT | POLLWRNORM));
431 
432 	FD_ZERO(&readfds);
433 	FD_ZERO(&writefds);
434 	FD_ZERO(&exceptfds);
435 	tv.tv_sec = 0;
436 	tv.tv_usec = 0;
437 	FD_SET(fd, &readfds);
438 	FD_SET(fd, &writefds);
439 	FD_SET(fd, &exceptfds);
440 	ATF_REQUIRE(select(fd + 1, &readfds, &writefds, &exceptfds, &tv) == 2);
441 	ATF_REQUIRE(FD_ISSET(fd, &readfds));
442 	ATF_REQUIRE(FD_ISSET(fd, &writefds));
443 	ATF_REQUIRE(!FD_ISSET(fd, &exceptfds));
444 
445 	/*
446 	 * Check that we get an EVFILT_READ event on fd.
447 	 */
448 	memset(kev, 0, sizeof(kev));
449 	ATF_REQUIRE(kevent(kq, NULL, 0, kev, 1, &ts) == 1);
450 	ATF_REQUIRE(kev[0].ident == (uintptr_t)fd);
451 	ATF_REQUIRE(kev[0].filter == EVFILT_READ);
452 	ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0);
453 	ATF_REQUIRE(kev[0].data == 1);
454 
455 	/*
456 	 * Read the timerfd to ensure we get the correct numnber of
457 	 * expirations.
458 	 */
459 	ATF_REQUIRE(timerfd_read(fd, &val) == 0);
460 	ATF_REQUIRE(val == 1);
461 
462 	/* And ensure that we would block if we tried again. */
463 	ATF_REQUIRE_ERRNO(EAGAIN, timerfd_read(fd, &val) == -1);
464 
465 	(void) close(kq);
466 	(void) close(fd);
467 }
468 
469 /*****************************************************************************/
470 
471 ATF_TC(timerfd_select_poll_kevent_block);
472 ATF_TC_HEAD(timerfd_select_poll_kevent_block, tc)
473 {
474 	atf_tc_set_md_var(tc, "descr",
475 	    "validates select/poll/kevent behavior - blocking");
476 }
477 ATF_TC_BODY(timerfd_select_poll_kevent_block, tc)
478 {
479 	const struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
480 	struct timespec then, now;
481 	struct pollfd fds[1];
482 	fd_set readfds;
483 	int fd;
484 	int kq;
485 	struct kevent kev[1];
486 
487 	ATF_REQUIRE((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) >= 0);
488 
489 	ATF_REQUIRE((kq = kqueue()) >= 0);
490 	EV_SET(&kev[0], fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
491 	ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, &ts) == 0);
492 
493 	/*
494 	 * For each of these tests, we do the following:
495 	 *
496 	 * - Get the current time.
497 	 * - Set a 1-second one-shot timer.
498 	 * - Block in the multiplexing call.
499 	 * - Get the current time and verify that the timer expiration
500 	 *   interval has passed.
501 	 */
502 
503 	const struct itimerspec its = {
504 		.it_value = { .tv_sec = 1, .tv_nsec = 0 },
505 		.it_interval = { .tv_sec = 0, .tv_nsec = 0 },
506 	};
507 
508 	/* poll(2) */
509 	fds[0].fd = fd;
510 	fds[0].events = POLLIN | POLLRDNORM;
511 	fds[0].revents = 0;
512 
513 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &then) == 0);
514 	ATF_REQUIRE(timerfd_settime(fd, 0, &its, NULL) == 0);
515 	ATF_REQUIRE(poll(fds, 1, INFTIM) == 1);
516 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &now) == 0);
517 	ATF_REQUIRE(fds[0].revents == (POLLIN | POLLRDNORM));
518 	ATF_REQUIRE(now.tv_sec - then.tv_sec >= 1);
519 
520 	/* select(2) */
521 	FD_ZERO(&readfds);
522 	FD_SET(fd, &readfds);
523 
524 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &then) == 0);
525 	ATF_REQUIRE(timerfd_settime(fd, 0, &its, NULL) == 0);
526 	ATF_REQUIRE(select(fd + 1, &readfds, NULL, NULL, NULL) == 1);
527 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &now) == 0);
528 	ATF_REQUIRE(FD_ISSET(fd, &readfds));
529 	ATF_REQUIRE(now.tv_sec - then.tv_sec >= 1);
530 
531 	/* kevent(2) */
532 	memset(kev, 0, sizeof(kev));
533 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &then) == 0);
534 	ATF_REQUIRE(timerfd_settime(fd, 0, &its, NULL) == 0);
535 	ATF_REQUIRE(kevent(kq, NULL, 0, kev, 1, NULL) == 1);
536 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &now) == 0);
537 	ATF_REQUIRE(kev[0].ident == (uintptr_t)fd);
538 	ATF_REQUIRE(kev[0].filter == EVFILT_READ);
539 	ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0);
540 	ATF_REQUIRE(kev[0].data == 1);
541 
542 	(void) close(kq);
543 	(void) close(fd);
544 }
545 
546 /*****************************************************************************/
547 
548 static void *
549 timerfd_restart_helper(void * const v)
550 {
551 	struct helper_context * const ctx = v;
552 
553 	ATF_REQUIRE(wait_barrier(ctx));
554 
555 	/*
556 	 * Wait 5 seconds (that should give the main thread time to
557 	 * block), and then close the descriptor.
558 	 */
559 	ATF_REQUIRE(sleep(5) == 0);
560 	ATF_REQUIRE(close(ctx->fd) == 0);
561 
562 	return NULL;
563 }
564 
565 ATF_TC(timerfd_restart);
566 ATF_TC_HEAD(timerfd_restart, tc)
567 {
568 	atf_tc_set_md_var(tc, "descr",
569 	    "exercises the 'restart' fileop code path");
570 }
571 ATF_TC_BODY(timerfd_restart, tc)
572 {
573 	struct timespec then, now, delta;
574 	struct helper_context ctx;
575 	uint64_t val;
576 	pthread_t helper;
577 	void *join_val;
578 
579 	init_helper_context(&ctx);
580 
581 	ATF_REQUIRE((ctx.fd = timerfd_create(CLOCK_MONOTONIC, 0)) >= 0);
582 
583 	const struct itimerspec its = {
584 		.it_value = { .tv_sec = 60 * 60, .tv_nsec = 0 },
585 		.it_interval = { .tv_sec = 0, .tv_nsec = 0 },
586 	};
587 	ATF_REQUIRE(timerfd_settime(ctx.fd, 0, &its, NULL) == 0);
588 
589 
590 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &then) == 0);
591 	ATF_REQUIRE(pthread_create(&helper, NULL,
592 				   timerfd_restart_helper, &ctx) == 0);
593 
594 	/*
595 	 * Wait for the helper to be ready, and then immediately block
596 	 * in read().  The helper will close the file, and we should get
597 	 * EBADF after a few seconds.
598 	 */
599 	ATF_REQUIRE(wait_barrier(&ctx));
600 	ATF_REQUIRE_ERRNO(EBADF, timerfd_read(ctx.fd, &val) == -1);
601 	ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &now) == 0);
602 
603 	timespecsub(&now, &then, &delta);
604 	ATF_REQUIRE(delta.tv_sec >= 5);
605 
606 	/* Reap the helper. */
607 	ATF_REQUIRE(pthread_join(helper, &join_val) == 0);
608 }
609 
610 /*****************************************************************************/
611 
612 ATF_TC(timerfd_fcntl);
613 ATF_TC_HEAD(timerfd_fcntl, tc)
614 {
615 	atf_tc_set_md_var(tc, "descr",
616 	    "validates fcntl behavior");
617 }
618 
619 ATF_TC_BODY(timerfd_fcntl, tc)
620 {
621 	int tfd;
622 	int val;
623 
624 	ATF_REQUIRE((tfd = timerfd_create(CLOCK_MONOTONIC, 0)) >= 0);
625 	ATF_REQUIRE((fcntl(tfd, F_GETFL) & O_NONBLOCK) == 0);
626 	ATF_REQUIRE(fcntl(tfd, F_SETFL, O_NONBLOCK) == 0);
627 	ATF_REQUIRE((fcntl(tfd, F_GETFL) & O_NONBLOCK) != 0);
628 	ATF_REQUIRE((fcntl(tfd, F_GETFD) & FD_CLOEXEC) == 0);
629 
630 	/* If the timer hasn't fired, there is no readable data. */
631 	ATF_REQUIRE(ioctl(tfd, FIONREAD, &val) == 0);
632 	ATF_REQUIRE(val == 0);
633 
634 	ATF_REQUIRE_ERRNO(ENOTTY, ioctl(tfd, FIONWRITE, &val) == -1);
635 	ATF_REQUIRE_ERRNO(ENOTTY, ioctl(tfd, FIONSPACE, &val) == -1);
636 	(void)close(tfd);
637 
638 	ATF_REQUIRE((tfd = timerfd_create(CLOCK_MONOTONIC,
639 					  TFD_NONBLOCK | TFD_CLOEXEC)) >= 0);
640 	ATF_REQUIRE((fcntl(tfd, F_GETFL) & ~O_ACCMODE) == O_NONBLOCK);
641 	ATF_REQUIRE((fcntl(tfd, F_GETFD) & FD_CLOEXEC) != 0);
642 	ATF_REQUIRE(fcntl(tfd, F_SETFD, 0) == 0);
643 	ATF_REQUIRE((fcntl(tfd, F_GETFD) & FD_CLOEXEC) == 0);
644 	ATF_REQUIRE(fcntl(tfd, F_SETFD, FD_CLOEXEC) == 0);
645 	ATF_REQUIRE((fcntl(tfd, F_GETFD) & FD_CLOEXEC) != 0);
646 	(void)close(tfd);
647 }
648 
649 /*****************************************************************************/
650 
651 ATF_TP_ADD_TCS(tp)
652 {
653 	ATF_TP_ADD_TC(tp, timerfd_create);
654 	ATF_TP_ADD_TC(tp, timerfd_bogusfd);
655 	ATF_TP_ADD_TC(tp, timerfd_block);
656 	ATF_TP_ADD_TC(tp, timerfd_repeating);
657 	ATF_TP_ADD_TC(tp, timerfd_abstime);
658 	ATF_TP_ADD_TC(tp, timerfd_cancel_on_set_block);
659 	ATF_TP_ADD_TC(tp, timerfd_cancel_on_set_immed);
660 	ATF_TP_ADD_TC(tp, timerfd_select_poll_kevent_immed);
661 	ATF_TP_ADD_TC(tp, timerfd_select_poll_kevent_block);
662 	ATF_TP_ADD_TC(tp, timerfd_restart);
663 	ATF_TP_ADD_TC(tp, timerfd_fcntl);
664 
665 	return atf_no_error();
666 }
667