1 /*
2 * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 /*
20 * Check that poll() timeouts correctly.
21 */
22 #include <unistd.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <sys/wait.h>
26 #include <sys/poll.h>
27
28 #include "test.h"
29 #include "safe_macros.h"
30
31 char *TCID = "poll02";
32 int TST_TOTAL = 1;
33
34 static char *opt_sleep_ms;
35
36 static option_t opts[] = {
37 {"s:", NULL, &opt_sleep_ms},
38 {NULL, NULL, NULL},
39 };
40
41 static void help(void);
42 static void setup(void);
43 static void cleanup(void);
44
45 static int fds[2];
46
main(int ac,char ** av)47 int main(int ac, char **av)
48 {
49 int lc, treshold;
50 long long elapsed_ms, sleep_ms = 100;
51
52 tst_parse_opts(ac, av, opts, help);
53
54 if (opt_sleep_ms) {
55 sleep_ms = atoll(opt_sleep_ms);
56
57 if (sleep_ms == 0)
58 tst_brkm(TBROK, NULL, "Invalid timeout '%s'", opt_sleep_ms);
59 }
60
61 treshold = sleep_ms / 100 + 10;
62
63 setup();
64
65 for (lc = 0; TEST_LOOPING(lc); lc++) {
66 struct pollfd pfds[] = {
67 {.fd = fds[0], .events = POLLIN}
68 };
69
70 tst_timer_start(CLOCK_MONOTONIC);
71 TEST(poll(pfds, 1, sleep_ms));
72 tst_timer_stop();
73
74 if (TEST_RETURN != 0) {
75 tst_resm(TFAIL, "poll() haven't timeouted ret=%li",
76 TEST_RETURN);
77 continue;
78 }
79
80 elapsed_ms = tst_timer_elapsed_ms();
81
82 if (elapsed_ms < sleep_ms) {
83 tst_resm(TFAIL,
84 "poll() woken up too early %llims, expected %llims",
85 elapsed_ms, sleep_ms);
86 continue;
87 }
88
89 if (elapsed_ms - sleep_ms > treshold) {
90 tst_resm(TFAIL,
91 "poll() slept too long %llims, expected %llims, threshold %i",
92 elapsed_ms, sleep_ms, treshold);
93 continue;
94 }
95
96 tst_resm(TPASS, "poll() slept %llims, expected %llims, treshold %i",
97 elapsed_ms, sleep_ms, treshold);
98 }
99
100 cleanup();
101 tst_exit();
102 }
103
setup(void)104 static void setup(void)
105 {
106 tst_timer_check(CLOCK_MONOTONIC);
107
108 SAFE_PIPE(NULL, fds);
109 }
110
cleanup(void)111 static void cleanup(void)
112 {
113 if (close(fds[0]))
114 tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
115
116 if (close(fds[1]))
117 tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
118 }
119
help(void)120 static void help(void)
121 {
122 printf(" -s poll() timeout lenght in ms\n");
123 }
124