1 #define _GNU_SOURCE
2
3 #include <atf-c.h>
4
5 #include <sys/types.h>
6
7 #ifndef __linux__
8 #include <sys/event.h>
9 #endif
10
11 #include <sys/param.h>
12 #include <sys/select.h>
13 #include <sys/time.h>
14
15 #include <errno.h>
16 #include <signal.h>
17 #include <stdbool.h>
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include <err.h>
23 #include <poll.h>
24 #include <time.h>
25 #include <unistd.h>
26
27 #include <sys/timerfd.h>
28
29 #include "atf-c-leakcheck.h"
30
31 // TODO(jan): Remove this once the definition is exposed in <sys/time.h> in
32 // all supported FreeBSD versions.
33 #ifndef timespecsub
34 #define timespecsub(tsp, usp, vsp) \
35 do { \
36 (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
37 (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
38 if ((vsp)->tv_nsec < 0) { \
39 (vsp)->tv_sec--; \
40 (vsp)->tv_nsec += 1000000000L; \
41 } \
42 } while (0)
43 #endif
44
45 #ifndef timespecadd
46 #define timespecadd(tsp, usp, vsp) \
47 do { \
48 (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
49 (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
50 if ((vsp)->tv_nsec >= 1000000000L) { \
51 (vsp)->tv_sec++; \
52 (vsp)->tv_nsec -= 1000000000L; \
53 } \
54 } while (0)
55 #endif
56
57 #ifndef nitems
58 #define nitems(x) (sizeof((x)) / sizeof((x)[0]))
59 #endif
60
61 /* Time in ns that sleeps are allowed to take longer for in unit tests. */
62 #define TIMER_SLACK (90000000)
63
64 ATF_TC_WITHOUT_HEAD(timerfd__many_timers);
ATF_TC_BODY(timerfd__many_timers,tc)65 ATF_TC_BODY(timerfd__many_timers, tc)
66 {
67 int timer_fds[256];
68 int i;
69
70 for (i = 0; i < (int)nitems(timer_fds); ++i) {
71 timer_fds[i] = timerfd_create(CLOCK_MONOTONIC, /**/
72 TFD_CLOEXEC | TFD_NONBLOCK);
73 if (timer_fds[i] < 0 && errno == EMFILE) {
74 atf_tc_skip("timerfd_create: EMFILE");
75 }
76 ATF_REQUIRE_MSG(timer_fds[i] >= 0, "errno: %d", errno);
77 }
78 }
79
80 static uint64_t
wait_for_timerfd(int timerfd)81 wait_for_timerfd(int timerfd)
82 {
83 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
84
85 ATF_REQUIRE(poll(&pfd, 1, -1) == 1);
86
87 uint64_t timeouts;
88 ssize_t r = read(timerfd, &timeouts, sizeof(timeouts));
89
90 ATF_REQUIRE_MSG(r == (ssize_t)sizeof(timeouts), "%d %d", (int)r, errno);
91 ATF_REQUIRE(timeouts > 0);
92 return timeouts;
93 }
94
95 ATF_TC_WITHOUT_HEAD(timerfd__simple_timer);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__simple_timer,tc)96 ATF_TC_BODY_FD_LEAKCHECK(timerfd__simple_timer, tc)
97 {
98 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
99 TFD_CLOEXEC | TFD_NONBLOCK);
100
101 ATF_REQUIRE(timerfd >= 0);
102
103 struct itimerspec time = {
104 .it_value.tv_sec = 0,
105 .it_value.tv_nsec = 100000000,
106 };
107
108 struct timespec b, e;
109 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
110
111 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
112 (void)wait_for_timerfd(timerfd);
113
114 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
115 timespecsub(&e, &b, &e);
116
117 ATF_REQUIRE(e.tv_sec == 0 && e.tv_nsec >= 100000000 &&
118 e.tv_nsec < 100000000 + TIMER_SLACK);
119
120 ATF_REQUIRE(close(timerfd) == 0);
121 }
122
123 ATF_TC_WITHOUT_HEAD(timerfd__simple_periodic_timer);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__simple_periodic_timer,tc)124 ATF_TC_BODY_FD_LEAKCHECK(timerfd__simple_periodic_timer, tc)
125 {
126 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
127 TFD_CLOEXEC | TFD_NONBLOCK);
128
129 ATF_REQUIRE(timerfd >= 0);
130
131 struct itimerspec time = {
132 .it_value.tv_sec = 0,
133 .it_value.tv_nsec = 200000000,
134 .it_interval.tv_sec = 0,
135 .it_interval.tv_nsec = 200000000,
136 };
137
138 struct timespec b, e;
139 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
140
141 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
142 uint64_t timeouts = wait_for_timerfd(timerfd);
143
144 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
145 timespecsub(&e, &b, &e);
146
147 ATF_REQUIRE(e.tv_sec == 0 && e.tv_nsec >= 200000000 &&
148 e.tv_nsec < 200000000 + TIMER_SLACK);
149 ATF_REQUIRE(timeouts == 1);
150
151 usleep(400000);
152
153 ATF_REQUIRE(read(timerfd, &timeouts, sizeof(timeouts)) ==
154 (ssize_t)sizeof(timeouts));
155 ATF_REQUIRE(timeouts == 2);
156
157 ATF_REQUIRE(close(timerfd) == 0);
158 }
159
160 ATF_TC_WITHOUT_HEAD(timerfd__complex_periodic_timer);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__complex_periodic_timer,tc)161 ATF_TC_BODY_FD_LEAKCHECK(timerfd__complex_periodic_timer, tc)
162 {
163 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
164 TFD_CLOEXEC | TFD_NONBLOCK);
165
166 ATF_REQUIRE(timerfd >= 0);
167
168 struct itimerspec time = {
169 .it_value.tv_sec = 0,
170 .it_value.tv_nsec = 100000000,
171 .it_interval.tv_sec = 0,
172 .it_interval.tv_nsec = 200000001,
173 };
174
175 struct timespec b, e;
176 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
177
178 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
179 uint64_t timeouts = wait_for_timerfd(timerfd);
180
181 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
182 timespecsub(&e, &b, &e);
183 ATF_REQUIRE_MSG(e.tv_sec == 0 && e.tv_nsec >= 100000000 &&
184 e.tv_nsec < 100000000 + TIMER_SLACK,
185 "%ld", (long)e.tv_nsec);
186
187 ATF_REQUIRE(timeouts == 1);
188
189 usleep(401000);
190
191 ATF_REQUIRE(read(timerfd, &timeouts, sizeof(timeouts)) ==
192 (ssize_t)sizeof(timeouts));
193 ATF_REQUIRE_MSG(timeouts == 2, "%d", (int)timeouts);
194
195 ATF_REQUIRE(close(timerfd) == 0);
196 }
197
198 ATF_TC_WITHOUT_HEAD(timerfd__reset_periodic_timer);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__reset_periodic_timer,tc)199 ATF_TC_BODY_FD_LEAKCHECK(timerfd__reset_periodic_timer, tc)
200 {
201 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
202 TFD_CLOEXEC | TFD_NONBLOCK);
203
204 ATF_REQUIRE(timerfd >= 0);
205
206 struct itimerspec time = {
207 .it_value.tv_sec = 0,
208 .it_value.tv_nsec = 100000000,
209 .it_interval.tv_sec = 0,
210 .it_interval.tv_nsec = 100000000,
211 };
212
213 struct timespec b, e;
214 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
215
216 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
217 (void)wait_for_timerfd(timerfd);
218
219 time = (struct itimerspec) {
220 .it_value.tv_sec = 0,
221 .it_value.tv_nsec = 50000000,
222 .it_interval.tv_sec = 0,
223 .it_interval.tv_nsec = 100000000,
224 };
225
226 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
227
228 uint64_t timeouts = wait_for_timerfd(timerfd);
229 ATF_REQUIRE(timeouts == 1);
230
231 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
232 timespecsub(&e, &b, &e);
233 ATF_REQUIRE(e.tv_sec == 0 && e.tv_nsec >= 150000000 &&
234 e.tv_nsec < 150000000 + TIMER_SLACK * 2);
235
236 ATF_REQUIRE(close(timerfd) == 0);
237 }
238
239 ATF_TC_WITHOUT_HEAD(timerfd__reenable_periodic_timer);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__reenable_periodic_timer,tc)240 ATF_TC_BODY_FD_LEAKCHECK(timerfd__reenable_periodic_timer, tc)
241 {
242 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
243 TFD_CLOEXEC | TFD_NONBLOCK);
244
245 ATF_REQUIRE(timerfd >= 0);
246
247 struct itimerspec time = {
248 .it_value.tv_sec = 0,
249 .it_value.tv_nsec = 100000000,
250 .it_interval.tv_sec = 0,
251 .it_interval.tv_nsec = 100000000,
252 };
253
254 struct timespec b, e;
255 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
256
257 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
258 uint64_t timeouts = wait_for_timerfd(timerfd);
259
260 ATF_REQUIRE(timeouts == 1);
261
262 time = (struct itimerspec) {
263 .it_value.tv_sec = 0,
264 .it_value.tv_nsec = 0,
265 .it_interval.tv_sec = 0,
266 .it_interval.tv_nsec = 0,
267 };
268
269 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
270
271 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
272 ATF_REQUIRE(poll(&pfd, 1, 250) == 0);
273
274 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
275 timespecsub(&e, &b, &e);
276
277 ATF_REQUIRE(e.tv_sec == 0 && e.tv_nsec >= 350000000 &&
278 e.tv_nsec < 350000000 + TIMER_SLACK * 2);
279
280 time = (struct itimerspec) {
281 .it_value.tv_sec = 1,
282 .it_value.tv_nsec = 0,
283 .it_interval.tv_sec = 1,
284 .it_interval.tv_nsec = 0,
285 };
286 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
287
288 ATF_REQUIRE(close(timerfd) == 0);
289 }
290
291 /*
292 * Adapted from sghctoma's example here:
293 * https://github.com/jiixyj/epoll-shim/issues/2
294 *
295 * The SIGUSR1 signal should not kill the process.
296 */
297 ATF_TC_WITHOUT_HEAD(timerfd__expire_five);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__expire_five,tc)298 ATF_TC_BODY_FD_LEAKCHECK(timerfd__expire_five, tc)
299 {
300 int fd;
301 struct itimerspec value;
302 uint64_t total_exp = 0;
303
304 fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
305 ATF_REQUIRE(fd >= 0);
306
307 value.it_value.tv_sec = 3;
308 value.it_value.tv_nsec = 0;
309 value.it_interval.tv_sec = 1;
310 value.it_interval.tv_nsec = 0;
311
312 ATF_REQUIRE(timerfd_settime(fd, 0, &value, NULL) == 0);
313
314 sigset_t sigs;
315 sigemptyset(&sigs);
316 sigaddset(&sigs, SIGUSR1);
317 sigprocmask(SIG_BLOCK, &sigs, NULL);
318
319 kill(getpid(), SIGUSR1);
320
321 for (;;) {
322 uint64_t exp = wait_for_timerfd(fd);
323
324 printf("timer expired %u times\n", (unsigned)exp);
325
326 total_exp += exp;
327 if (total_exp >= 5) {
328 break;
329 }
330 }
331
332 ATF_REQUIRE(close(fd) == 0);
333 }
334
335 ATF_TC_WITHOUT_HEAD(timerfd__simple_gettime);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__simple_gettime,tc)336 ATF_TC_BODY_FD_LEAKCHECK(timerfd__simple_gettime, tc)
337 {
338 struct itimerspec curr_value;
339
340 int fd = timerfd_create(CLOCK_MONOTONIC, 0);
341 ATF_REQUIRE(fd >= 0);
342
343 ATF_REQUIRE(timerfd_gettime(fd, &curr_value) == 0);
344
345 ATF_REQUIRE(curr_value.it_value.tv_sec == 0);
346 ATF_REQUIRE(curr_value.it_value.tv_nsec == 0);
347 ATF_REQUIRE(curr_value.it_interval.tv_sec == 0);
348 ATF_REQUIRE(curr_value.it_interval.tv_nsec == 0);
349
350 struct itimerspec time = {
351 .it_value.tv_sec = 0,
352 .it_value.tv_nsec = 100000000,
353 .it_interval.tv_sec = 0,
354 .it_interval.tv_nsec = 100000000,
355 };
356
357 curr_value = time;
358 ATF_REQUIRE(timerfd_settime(fd, 0, &time, &curr_value) == 0);
359 ATF_REQUIRE(curr_value.it_value.tv_sec == 0);
360 ATF_REQUIRE(curr_value.it_value.tv_nsec == 0);
361 ATF_REQUIRE(curr_value.it_interval.tv_sec == 0);
362 ATF_REQUIRE(curr_value.it_interval.tv_nsec == 0);
363
364 ATF_REQUIRE(close(fd) == 0);
365 }
366
367 ATF_TC_WITHOUT_HEAD(timerfd__simple_blocking_periodic_timer);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__simple_blocking_periodic_timer,tc)368 ATF_TC_BODY_FD_LEAKCHECK(timerfd__simple_blocking_periodic_timer, tc)
369 {
370 int timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
371
372 ATF_REQUIRE(timerfd >= 0);
373
374 struct itimerspec time = {
375 .it_value.tv_sec = 0,
376 .it_value.tv_nsec = 100000000,
377 .it_interval.tv_sec = 0,
378 .it_interval.tv_nsec = 100000000,
379 };
380
381 struct timespec b, e;
382 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
383
384 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
385
386 uint64_t timeouts = 0;
387 int num_loop_iterations = 0;
388
389 while (timeouts < 3) {
390 uint64_t timeouts_local;
391 ATF_REQUIRE(
392 read(timerfd, &timeouts_local, sizeof(timeouts_local)) ==
393 (ssize_t)sizeof(timeouts_local));
394 ATF_REQUIRE(timeouts_local > 0);
395
396 ++num_loop_iterations;
397 timeouts += timeouts_local;
398 }
399
400 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
401 timespecsub(&e, &b, &e);
402
403 ATF_REQUIRE(e.tv_sec == 0 && e.tv_nsec >= 300000000 &&
404 e.tv_nsec < 300000000 + TIMER_SLACK);
405
406 ATF_REQUIRE(num_loop_iterations <= 3);
407
408 ATF_REQUIRE(close(timerfd) == 0);
409 }
410
411 ATF_TC_WITHOUT_HEAD(timerfd__argument_checks);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__argument_checks,tc)412 ATF_TC_BODY_FD_LEAKCHECK(timerfd__argument_checks, tc)
413 {
414 int timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
415 ATF_REQUIRE(timerfd >= 0);
416
417 struct itimerspec time = {
418 .it_value.tv_sec = 0,
419 .it_value.tv_nsec = 100000000,
420 .it_interval.tv_sec = 0,
421 .it_interval.tv_nsec = 100000000,
422 };
423
424 ATF_REQUIRE_ERRNO(EFAULT, timerfd_settime(timerfd, 0, NULL, NULL) < 0);
425 ATF_REQUIRE_ERRNO(EFAULT, timerfd_settime(-2, 0, NULL, NULL) < 0);
426 ATF_REQUIRE_ERRNO(EBADF, timerfd_settime(-2, 0, &time, NULL) < 0);
427 ATF_REQUIRE_ERRNO(EFAULT, timerfd_settime(-2, 42, NULL, NULL) < 0);
428 ATF_REQUIRE_ERRNO(EINVAL, timerfd_settime(-2, 42, &time, NULL) < 0);
429 ATF_REQUIRE_ERRNO(EINVAL,
430 timerfd_settime(timerfd, 42, &time, NULL) < 0);
431
432 {
433 time = (struct itimerspec) {
434 .it_value.tv_sec = -1,
435 .it_value.tv_nsec = 100000000,
436 .it_interval.tv_sec = 0,
437 .it_interval.tv_nsec = 100000000,
438 };
439 ATF_REQUIRE_ERRNO(EINVAL,
440 timerfd_settime(timerfd, 0, &time, NULL) < 0);
441 }
442 {
443 time = (struct itimerspec) {
444 .it_value.tv_sec = 0,
445 .it_value.tv_nsec = -1,
446 .it_interval.tv_sec = 0,
447 .it_interval.tv_nsec = 100000000,
448 };
449 ATF_REQUIRE_ERRNO(EINVAL,
450 timerfd_settime(timerfd, 0, &time, NULL) < 0);
451 }
452 {
453 time = (struct itimerspec) {
454 .it_value.tv_sec = 0,
455 .it_value.tv_nsec = 100000000,
456 .it_interval.tv_sec = -1,
457 .it_interval.tv_nsec = 100000000,
458 };
459 ATF_REQUIRE_ERRNO(EINVAL,
460 timerfd_settime(timerfd, 0, &time, NULL) < 0);
461 }
462 {
463 time = (struct itimerspec) {
464 .it_value.tv_sec = 0,
465 .it_value.tv_nsec = 100000000,
466 .it_interval.tv_sec = 0,
467 .it_interval.tv_nsec = -1,
468 };
469 ATF_REQUIRE_ERRNO(EINVAL,
470 timerfd_settime(timerfd, 0, &time, NULL) < 0);
471 }
472 {
473 time = (struct itimerspec) {
474 .it_value.tv_sec = 0,
475 .it_value.tv_nsec = 1000000000,
476 .it_interval.tv_sec = 0,
477 .it_interval.tv_nsec = 100000000,
478 };
479 ATF_REQUIRE_ERRNO(EINVAL,
480 timerfd_settime(timerfd, 0, &time, NULL) < 0);
481 }
482 {
483 time = (struct itimerspec) {
484 .it_value.tv_sec = 0,
485 .it_value.tv_nsec = 100000000,
486 .it_interval.tv_sec = 0,
487 .it_interval.tv_nsec = 1000000000,
488 };
489 ATF_REQUIRE_ERRNO(EINVAL,
490 timerfd_settime(timerfd, 0, &time, NULL) < 0);
491 }
492
493 ATF_REQUIRE_ERRNO(EINVAL,
494 timerfd_create(CLOCK_MONOTONIC | 42, TFD_CLOEXEC));
495 ATF_REQUIRE_ERRNO(EINVAL,
496 timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | 42));
497
498 ATF_REQUIRE(close(timerfd) == 0);
499
500 struct itimerspec itimerspec;
501 ATF_REQUIRE_ERRNO(EBADF, timerfd_gettime(timerfd, &itimerspec) < 0);
502
503 ATF_REQUIRE(timerfd_settime(timerfd, 0, &itimerspec, NULL) < 0);
504 /* Linux 5.10 returns EINVAL instead of EBADF. */
505 ATF_REQUIRE(errno == EBADF || errno == EINVAL);
506 }
507
508 ATF_TC_WITHOUT_HEAD(timerfd__upgrade_simple_to_complex);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__upgrade_simple_to_complex,tc)509 ATF_TC_BODY_FD_LEAKCHECK(timerfd__upgrade_simple_to_complex, tc)
510 {
511 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
512 TFD_CLOEXEC | TFD_NONBLOCK);
513
514 ATF_REQUIRE(timerfd >= 0);
515
516 struct itimerspec time = {
517 .it_value.tv_sec = 0,
518 .it_value.tv_nsec = 100000000,
519 .it_interval.tv_sec = 0,
520 .it_interval.tv_nsec = 100000000,
521 };
522
523 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
524 (void)wait_for_timerfd(timerfd);
525
526 time = (struct itimerspec) {
527 .it_value.tv_sec = 0,
528 .it_value.tv_nsec = 50000000,
529 .it_interval.tv_sec = 0,
530 .it_interval.tv_nsec = 95000000,
531 };
532
533 struct timespec b, e;
534 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
535
536 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
537
538 uint64_t timeouts = wait_for_timerfd(timerfd);
539 ATF_REQUIRE(timeouts == 1);
540
541 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
542 timespecsub(&e, &b, &e);
543 ATF_REQUIRE_MSG(e.tv_sec == 0 && e.tv_nsec >= 50000000 &&
544 e.tv_nsec < 50000000 + TIMER_SLACK,
545 "%ld", e.tv_nsec);
546
547 timeouts = wait_for_timerfd(timerfd);
548 ATF_REQUIRE(timeouts == 1);
549
550 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
551 timespecsub(&e, &b, &e);
552 ATF_REQUIRE(e.tv_sec == 0 && e.tv_nsec >= 145000000 &&
553 e.tv_nsec < 145000000 + TIMER_SLACK);
554
555 ATF_REQUIRE(close(timerfd) == 0);
556 }
557
558 ATF_TC_WITHOUT_HEAD(timerfd__absolute_timer);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__absolute_timer,tc)559 ATF_TC_BODY_FD_LEAKCHECK(timerfd__absolute_timer, tc)
560 {
561 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
562 TFD_CLOEXEC | TFD_NONBLOCK);
563
564 ATF_REQUIRE(timerfd >= 0);
565
566 struct timespec b, e;
567 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
568
569 struct itimerspec time = {
570 .it_value = b,
571 .it_interval.tv_sec = 0,
572 .it_interval.tv_nsec = 0,
573 };
574
575 struct timespec ts_600ms = {
576 .tv_sec = 0,
577 .tv_nsec = 600000000,
578 };
579
580 timespecadd(&time.it_value, &ts_600ms, &time.it_value);
581
582 ATF_REQUIRE(timerfd_settime(timerfd, /**/
583 TFD_TIMER_ABSTIME, &time, NULL) == 0);
584
585 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
586 ATF_REQUIRE(poll(&pfd, 1, -1) == 1);
587
588 // Don't read(2) here!
589
590 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
591 timespecsub(&e, &b, &e);
592 ATF_REQUIRE(e.tv_sec == 0 &&
593 /* Don't check for this because of spurious wakeups. */
594 /* e.tv_nsec >= 600000000 && */
595 e.tv_nsec < 600000000 + TIMER_SLACK);
596
597 struct itimerspec zeroed_its = {
598 .it_value.tv_sec = 0,
599 .it_value.tv_nsec = 0,
600 .it_interval.tv_sec = 0,
601 .it_interval.tv_nsec = 0,
602 };
603 ATF_REQUIRE(timerfd_settime(timerfd, 0, &zeroed_its, NULL) == 0);
604
605 uint64_t timeouts;
606 ATF_REQUIRE_ERRNO(EAGAIN,
607 read(timerfd, &timeouts, sizeof(timeouts)) < 0);
608
609 ATF_REQUIRE(poll(&pfd, 1, 0) == 0);
610
611 ATF_REQUIRE(close(timerfd) == 0);
612 }
613
614 ATF_TC_WITHOUT_HEAD(timerfd__absolute_timer_in_the_past);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__absolute_timer_in_the_past,tc)615 ATF_TC_BODY_FD_LEAKCHECK(timerfd__absolute_timer_in_the_past, tc)
616 {
617 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
618 TFD_CLOEXEC | TFD_NONBLOCK);
619
620 ATF_REQUIRE(timerfd >= 0);
621
622 struct timespec b;
623 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
624
625 {
626 struct itimerspec time = {
627 .it_value = b,
628 .it_interval.tv_sec = 10,
629 .it_interval.tv_nsec = 0,
630 };
631 time.it_value.tv_sec -= 1;
632
633 ATF_REQUIRE(timerfd_settime(timerfd, /**/
634 TFD_TIMER_ABSTIME, &time, NULL) == 0);
635
636 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
637 ATF_REQUIRE(poll(&pfd, 1, 1000) == 1);
638 }
639
640 {
641 struct itimerspec time = {
642 .it_value = b,
643 .it_interval.tv_sec = 0,
644 .it_interval.tv_nsec = 10000000,
645 };
646 time.it_value.tv_sec -= 1;
647
648 ATF_REQUIRE(timerfd_settime(timerfd, /**/
649 TFD_TIMER_ABSTIME, &time, NULL) == 0);
650
651 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
652 ATF_REQUIRE(poll(&pfd, 1, -1) == 1);
653 }
654
655 uint64_t timeouts;
656 ATF_REQUIRE(read(timerfd, &timeouts, sizeof(timeouts)) ==
657 (ssize_t)sizeof(timeouts));
658
659 ATF_REQUIRE_MSG(timeouts >= 101, "%d", (int)timeouts);
660
661 ATF_REQUIRE(close(timerfd) == 0);
662 }
663
664 ATF_TC_WITHOUT_HEAD(timerfd__reset_absolute);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__reset_absolute,tc)665 ATF_TC_BODY_FD_LEAKCHECK(timerfd__reset_absolute, tc)
666 {
667 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
668 TFD_CLOEXEC | TFD_NONBLOCK);
669
670 ATF_REQUIRE(timerfd >= 0);
671
672 struct timespec b;
673 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
674
675 {
676 struct itimerspec time = {
677 .it_value = b,
678 };
679 time.it_value.tv_sec += 10;
680
681 ATF_REQUIRE(timerfd_settime(timerfd, /**/
682 TFD_TIMER_ABSTIME, &time, NULL) == 0);
683
684 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
685 ATF_REQUIRE(poll(&pfd, 1, 100) == 0);
686 }
687
688 {
689 struct itimerspec time = {
690 .it_value = b,
691 };
692 time.it_value.tv_nsec += 500000000;
693 if (time.it_value.tv_nsec >= 1000000000) {
694 time.it_value.tv_nsec -= 1000000000;
695 time.it_value.tv_sec += 1;
696 }
697
698 ATF_REQUIRE(timerfd_settime(timerfd, /**/
699 TFD_TIMER_ABSTIME, &time, NULL) == 0);
700
701 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
702 ATF_REQUIRE(poll(&pfd, 1, 1000) == 1);
703 }
704
705 uint64_t timeouts;
706 ATF_REQUIRE(read(timerfd, &timeouts, sizeof(timeouts)) ==
707 (ssize_t)sizeof(timeouts));
708
709 ATF_REQUIRE_MSG(timeouts == 1, "%d", (int)timeouts);
710
711 ATF_REQUIRE(close(timerfd) == 0);
712 }
713
714 ATF_TC(timerfd__periodic_timer_performance);
ATF_TC_HEAD(timerfd__periodic_timer_performance,tc)715 ATF_TC_HEAD(timerfd__periodic_timer_performance, tc)
716 {
717 atf_tc_set_md_var(tc, "timeout", "1");
718 }
ATF_TC_BODY_FD_LEAKCHECK(timerfd__periodic_timer_performance,tc)719 ATF_TC_BODY_FD_LEAKCHECK(timerfd__periodic_timer_performance, tc)
720 {
721 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
722 TFD_CLOEXEC | TFD_NONBLOCK);
723
724 ATF_REQUIRE(timerfd >= 0);
725
726 struct itimerspec time = {
727 .it_value.tv_sec = 0,
728 .it_value.tv_nsec = 1,
729 .it_interval.tv_sec = 0,
730 .it_interval.tv_nsec = 1,
731 };
732
733 ATF_REQUIRE(timerfd_settime(timerfd, 0, &time, NULL) == 0);
734
735 usleep(400000);
736
737 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
738 ATF_REQUIRE(poll(&pfd, 1, -1) == 1);
739
740 uint64_t timeouts;
741 ATF_REQUIRE(read(timerfd, &timeouts, sizeof(timeouts)) ==
742 (ssize_t)sizeof(timeouts));
743 ATF_REQUIRE(timeouts >= 400000000);
744
745 ATF_REQUIRE(close(timerfd) == 0);
746 }
747
748 ATF_TC_WITHOUT_HEAD(timerfd__argument_overflow);
ATF_TC_BODY_FD_LEAKCHECK(timerfd__argument_overflow,tc)749 ATF_TC_BODY_FD_LEAKCHECK(timerfd__argument_overflow, tc)
750 {
751 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
752 TFD_CLOEXEC | TFD_NONBLOCK);
753 ATF_REQUIRE(timerfd >= 0);
754 {
755 struct itimerspec time = {
756 .it_value.tv_sec = 0,
757 .it_value.tv_nsec = 1,
758 };
759
760 ATF_REQUIRE(timerfd_settime(timerfd, /**/
761 TFD_TIMER_ABSTIME, &time, NULL) == 0);
762
763 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
764 ATF_REQUIRE(poll(&pfd, 1, -1) == 1);
765
766 uint64_t timeouts;
767 ATF_REQUIRE(read(timerfd, &timeouts, sizeof(timeouts)) ==
768 (ssize_t)sizeof(timeouts));
769 ATF_REQUIRE(timeouts == 1);
770
771 ATF_REQUIRE(read(timerfd, &timeouts, sizeof(timeouts)) < 0);
772 }
773 {
774 struct itimerspec time = {
775 .it_value.tv_sec = INT_MAX,
776 .it_value.tv_nsec = 999999999,
777 };
778
779 ATF_REQUIRE(timerfd_settime(timerfd, /**/
780 TFD_TIMER_ABSTIME, &time, NULL) == 0);
781
782 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
783 ATF_REQUIRE(poll(&pfd, 1, 500) == 0);
784
785 uint64_t timeouts;
786 ATF_REQUIRE(read(timerfd, &timeouts, sizeof(timeouts)) < 0);
787 }
788
789 ATF_REQUIRE(close(timerfd) == 0);
790 }
791
792 ATF_TC(timerfd__short_evfilt_timer_timeout);
ATF_TC_HEAD(timerfd__short_evfilt_timer_timeout,tc)793 ATF_TC_HEAD(timerfd__short_evfilt_timer_timeout, tc)
794 {
795 atf_tc_set_md_var(tc, "timeout", "30");
796 }
ATF_TC_BODY_FD_LEAKCHECK(timerfd__short_evfilt_timer_timeout,tc)797 ATF_TC_BODY_FD_LEAKCHECK(timerfd__short_evfilt_timer_timeout, tc)
798 {
799 #ifndef __linux__
800 int kq = kqueue();
801 ATF_REQUIRE(kq >= 0);
802
803 bool returns_early = false;
804
805 #ifdef __NetBSD__
806 /*
807 * Expect that NetBSD's EVFILT_TIMER returns early at some point. The
808 * test should exceed the timeout and thus fail if/when this bug is
809 * fixed in NetBSD.
810 */
811 for (;;) {
812 #else
813 for (int l = 0; l < 10; ++l) {
814 #endif
815 for (int i = 1; i <= 17; ++i) {
816 struct kevent kev;
817 EV_SET(&kev, 0, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, i,
818 0);
819
820 struct timespec b;
821 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
822
823 ATF_REQUIRE(kevent(kq, &kev, 1, NULL, 0, NULL) == 0);
824
825 ATF_REQUIRE(kevent(kq, NULL, 0, &kev, 1, NULL) == 1);
826
827 struct timespec e;
828 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
829
830 struct timespec diff;
831 timespecsub(&e, &b, &diff);
832
833 if (diff.tv_sec != 0 || diff.tv_nsec < i * 1000000) {
834 fprintf(stderr,
835 "expected: %lldns, got: %lldns\n",
836 (long long)(i * 1000000LL),
837 (long long)diff.tv_nsec);
838 returns_early = true;
839 goto check;
840 }
841 }
842 }
843
844 check:
845 #ifdef __NetBSD__
846 ATF_REQUIRE(returns_early);
847 #else
848 ATF_REQUIRE(!returns_early);
849 #endif
850
851 ATF_REQUIRE(close(kq) == 0);
852 #endif
853
854 /*
855 * timerfd's should never return early, regardless of how
856 * EVFILT_TIMER behaves.
857 */
858
859 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
860 TFD_CLOEXEC | TFD_NONBLOCK);
861
862 ATF_REQUIRE(timerfd >= 0);
863
864 for (int l = 0; l < 10; ++l) {
865 for (int i = 1; i <= 17; ++i) {
866 struct itimerspec time = {
867 .it_value.tv_sec = 0,
868 .it_value.tv_nsec = i * 1000000,
869 };
870
871 struct timespec b;
872 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &b) == 0);
873
874 ATF_REQUIRE(
875 timerfd_settime(timerfd, 0, &time, NULL) == 0);
876 (void)wait_for_timerfd(timerfd);
877
878 struct timespec e;
879 ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &e) == 0);
880
881 struct timespec diff;
882 timespecsub(&e, &b, &diff);
883
884 ATF_REQUIRE(
885 diff.tv_sec == 0 && diff.tv_nsec >= i * 1000000);
886 fprintf(stderr, "%dms, waited %lldns\n", i,
887 (long long)diff.tv_nsec);
888 }
889 }
890
891 ATF_REQUIRE(close(timerfd) == 0);
892 }
893
894 ATF_TC_WITHOUT_HEAD(timerfd__unmodified_errno);
895 ATF_TC_BODY_FD_LEAKCHECK(timerfd__unmodified_errno, tc)
896 {
897 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
898 TFD_CLOEXEC | TFD_NONBLOCK);
899 ATF_REQUIRE(timerfd >= 0);
900 ATF_REQUIRE(errno == 0);
901
902 ATF_REQUIRE(timerfd_settime(timerfd, 0,
903 &(struct itimerspec) {
904 .it_value.tv_sec = 0,
905 .it_value.tv_nsec = 100000000,
906 },
907 NULL) == 0);
908 (void)wait_for_timerfd(timerfd);
909 ATF_REQUIRE(errno == 0);
910
911 ATF_REQUIRE(timerfd_settime(timerfd, 0,
912 &(struct itimerspec) {
913 .it_value.tv_sec = 0,
914 .it_value.tv_nsec = 0,
915 },
916 NULL) == 0);
917 ATF_REQUIRE(errno == 0);
918
919 ATF_REQUIRE(timerfd_settime(timerfd, 0,
920 &(struct itimerspec) {
921 .it_value.tv_sec = 0,
922 .it_value.tv_nsec = 0,
923 },
924 NULL) == 0);
925 ATF_REQUIRE(errno == 0);
926
927 ATF_REQUIRE(close(timerfd) == 0);
928 ATF_REQUIRE(errno == 0);
929 }
930
931 ATF_TC_WITHOUT_HEAD(timerfd__reset_to_very_long);
932 ATF_TC_BODY_FD_LEAKCHECK(timerfd__reset_to_very_long, tc)
933 {
934 int timerfd = timerfd_create(CLOCK_MONOTONIC, /**/
935 TFD_CLOEXEC | TFD_NONBLOCK);
936 ATF_REQUIRE(timerfd >= 0);
937 ATF_REQUIRE(errno == 0);
938
939 ATF_REQUIRE(timerfd_settime(timerfd, 0,
940 &(struct itimerspec) {
941 .it_value.tv_sec = 0,
942 .it_value.tv_nsec = 100000000,
943 },
944 NULL) == 0);
945 ATF_REQUIRE(errno == 0);
946
947 ATF_REQUIRE(timerfd_settime(timerfd, 0,
948 &(struct itimerspec) {
949 .it_value.tv_sec = 630720000,
950 .it_value.tv_nsec = 0,
951 },
952 NULL) == 0);
953 ATF_REQUIRE(errno == 0);
954
955 struct pollfd pfd = { .fd = timerfd, .events = POLLIN };
956 ATF_REQUIRE(poll(&pfd, 1, 500) == 0);
957 uint64_t timeouts;
958 ssize_t r = read(timerfd, &timeouts, sizeof(timeouts));
959 ATF_REQUIRE_ERRNO(EAGAIN, r < 0);
960
961 ATF_REQUIRE(close(timerfd) == 0);
962 ATF_REQUIRE(errno == EAGAIN);
963 }
964
965 ATF_TP_ADD_TCS(tp)
966 {
967 ATF_TP_ADD_TC(tp, timerfd__many_timers);
968 ATF_TP_ADD_TC(tp, timerfd__simple_timer);
969 ATF_TP_ADD_TC(tp, timerfd__simple_periodic_timer);
970 ATF_TP_ADD_TC(tp, timerfd__complex_periodic_timer);
971 ATF_TP_ADD_TC(tp, timerfd__reset_periodic_timer);
972 ATF_TP_ADD_TC(tp, timerfd__reenable_periodic_timer);
973 ATF_TP_ADD_TC(tp, timerfd__expire_five);
974 ATF_TP_ADD_TC(tp, timerfd__simple_gettime);
975 ATF_TP_ADD_TC(tp, timerfd__simple_blocking_periodic_timer);
976 ATF_TP_ADD_TC(tp, timerfd__argument_checks);
977 ATF_TP_ADD_TC(tp, timerfd__upgrade_simple_to_complex);
978 ATF_TP_ADD_TC(tp, timerfd__absolute_timer);
979 ATF_TP_ADD_TC(tp, timerfd__absolute_timer_in_the_past);
980 ATF_TP_ADD_TC(tp, timerfd__reset_absolute);
981 ATF_TP_ADD_TC(tp, timerfd__periodic_timer_performance);
982 ATF_TP_ADD_TC(tp, timerfd__argument_overflow);
983 ATF_TP_ADD_TC(tp, timerfd__short_evfilt_timer_timeout);
984 ATF_TP_ADD_TC(tp, timerfd__unmodified_errno);
985 ATF_TP_ADD_TC(tp, timerfd__reset_to_very_long);
986
987 return atf_no_error();
988 }
989