Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | | - |
19 | | - |
20 | | - |
21 | #include <config.h> | - |
22 | | - |
23 | #include <time.h> | - |
24 | | - |
25 | #include "intprops.h" | - |
26 | #include "sig-handler.h" | - |
27 | #include "verify.h" | - |
28 | | - |
29 | #include <stdbool.h> | - |
30 | #include <stdio.h> | - |
31 | #include <sys/types.h> | - |
32 | #include <sys/select.h> | - |
33 | #include <signal.h> | - |
34 | | - |
35 | #include <sys/time.h> | - |
36 | #include <errno.h> | - |
37 | | - |
38 | #include <unistd.h> | - |
39 | | - |
40 | | - |
41 | enum { BILLION = 1000 * 1000 * 1000 }; | - |
42 | | - |
43 | #if HAVE_BUG_BIG_NANOSLEEP | - |
44 | | - |
45 | int | - |
46 | nanosleep (const struct timespec *requested_delay, | - |
47 | struct timespec *remaining_delay) | - |
48 | # undef nanosleep | - |
49 | { | - |
50 | | - |
51 | | - |
52 | | - |
53 | | - |
54 | | - |
55 | | - |
56 | if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec)TRUE | never evaluated | FALSE | evaluated 459 times by 2 tests |
TRUE | never evaluated | FALSE | evaluated 459 times by 2 tests |
| 0-459 |
57 | { | - |
58 | errno = EINVAL; | - |
59 | return -1; never executed: return -1; | 0 |
60 | } | - |
61 | | - |
62 | { | - |
63 | | - |
64 | verify (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60); | - |
65 | const time_t limit = 24 * 24 * 60 * 60; | - |
66 | time_t seconds = requested_delay->tv_sec; | - |
67 | struct timespec intermediate; | - |
68 | intermediate.tv_nsec = requested_delay->tv_nsec; | - |
69 | | - |
70 | while (limit < seconds)TRUE | evaluated 2 times by 1 test | FALSE | evaluated 457 times by 2 tests |
| 2-457 |
71 | { | - |
72 | int result; | - |
73 | intermediate.tv_sec = limit; | - |
74 | result = nanosleep (&intermediate, remaining_delay); | - |
75 | seconds -= limit; | - |
76 | if (result)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
77 | { | - |
78 | if (remaining_delay)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
79 | remaining_delay->tv_sec += seconds; never executed: remaining_delay->tv_sec += seconds; | 0 |
80 | return result; never executed: return result; | 0 |
81 | } | - |
82 | intermediate.tv_nsec = 0; | - |
83 | } never executed: end of block | 0 |
84 | intermediate.tv_sec = seconds; | - |
85 | return nanosleep (&intermediate, remaining_delay);executed 457 times by 2 tests: return nanosleep (&intermediate, remaining_delay); | 457 |
86 | } | - |
87 | } | - |
88 | | - |
89 | #elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | - |
90 | | - |
91 | | - |
92 | # define WIN32_LEAN_AND_MEAN | - |
93 | # include <windows.h> | - |
94 | | - |
95 | | - |
96 | | - |
97 | | - |
98 | | - |
99 | | - |
100 | | - |
101 | int | - |
102 | nanosleep (const struct timespec *requested_delay, | - |
103 | struct timespec *remaining_delay) | - |
104 | { | - |
105 | static bool initialized; | - |
106 | | - |
107 | | - |
108 | static double ticks_per_nanosecond; | - |
109 | | - |
110 | if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) | - |
111 | { | - |
112 | errno = EINVAL; | - |
113 | return -1; | - |
114 | } | - |
115 | | - |
116 | | - |
117 | | - |
118 | if (requested_delay->tv_sec == 0) | - |
119 | { | - |
120 | if (!initialized) | - |
121 | { | - |
122 | | - |
123 | LARGE_INTEGER ticks_per_second; | - |
124 | | - |
125 | if (QueryPerformanceFrequency (&ticks_per_second)) | - |
126 | ticks_per_nanosecond = | - |
127 | (double) ticks_per_second.QuadPart / 1000000000.0; | - |
128 | | - |
129 | initialized = true; | - |
130 | } | - |
131 | if (ticks_per_nanosecond) | - |
132 | { | - |
133 | | - |
134 | | - |
135 | | - |
136 | | - |
137 | | - |
138 | | - |
139 | int sleep_millis = (int) requested_delay->tv_nsec / 1000000 - 10; | - |
140 | | - |
141 | LONGLONG wait_ticks = requested_delay->tv_nsec * ticks_per_nanosecond; | - |
142 | | - |
143 | LARGE_INTEGER counter_before; | - |
144 | if (QueryPerformanceCounter (&counter_before)) | - |
145 | { | - |
146 | | - |
147 | | - |
148 | | - |
149 | | - |
150 | LONGLONG wait_until = counter_before.QuadPart + wait_ticks; | - |
151 | | - |
152 | if (sleep_millis > 0) | - |
153 | Sleep (sleep_millis); | - |
154 | | - |
155 | for (;;) | - |
156 | { | - |
157 | LARGE_INTEGER counter_after; | - |
158 | if (!QueryPerformanceCounter (&counter_after)) | - |
159 | | - |
160 | | - |
161 | break; | - |
162 | if (counter_after.QuadPart >= wait_until) | - |
163 | | - |
164 | break; | - |
165 | } | - |
166 | goto done; | - |
167 | } | - |
168 | } | - |
169 | } | - |
170 | | - |
171 | Sleep (requested_delay->tv_sec * 1000 + requested_delay->tv_nsec / 1000000); | - |
172 | | - |
173 | done: | - |
174 | | - |
175 | if (remaining_delay != NULL) | - |
176 | { | - |
177 | remaining_delay->tv_sec = 0; | - |
178 | remaining_delay->tv_nsec = 0; | - |
179 | } | - |
180 | return 0; | - |
181 | } | - |
182 | | - |
183 | #else | - |
184 | | - |
185 | | - |
186 | | - |
187 | | - |
188 | | - |
189 | # ifndef SIGCONT | - |
190 | # define SIGCONT SIGTERM | - |
191 | # endif | - |
192 | | - |
193 | static sig_atomic_t volatile suspended; | - |
194 | | - |
195 | | - |
196 | | - |
197 | static void | - |
198 | sighandler (int sig) | - |
199 | { | - |
200 | suspended = 1; | - |
201 | } | - |
202 | | - |
203 | | - |
204 | | - |
205 | static int | - |
206 | my_usleep (const struct timespec *ts_delay) | - |
207 | { | - |
208 | struct timeval tv_delay; | - |
209 | tv_delay.tv_sec = ts_delay->tv_sec; | - |
210 | tv_delay.tv_usec = (ts_delay->tv_nsec + 999) / 1000; | - |
211 | if (tv_delay.tv_usec == 1000000) | - |
212 | { | - |
213 | if (tv_delay.tv_sec == TYPE_MAXIMUM (time_t)) | - |
214 | tv_delay.tv_usec = 1000000 - 1; | - |
215 | else | - |
216 | { | - |
217 | tv_delay.tv_sec++; | - |
218 | tv_delay.tv_usec = 0; | - |
219 | } | - |
220 | } | - |
221 | return select (0, NULL, NULL, NULL, &tv_delay); | - |
222 | } | - |
223 | | - |
224 | | - |
225 | | - |
226 | | - |
227 | int | - |
228 | nanosleep (const struct timespec *requested_delay, | - |
229 | struct timespec *remaining_delay) | - |
230 | { | - |
231 | static bool initialized; | - |
232 | | - |
233 | if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) | - |
234 | { | - |
235 | errno = EINVAL; | - |
236 | return -1; | - |
237 | } | - |
238 | | - |
239 | | - |
240 | if (! initialized) | - |
241 | { | - |
242 | struct sigaction oldact; | - |
243 | | - |
244 | sigaction (SIGCONT, NULL, &oldact); | - |
245 | if (get_handler (&oldact) != SIG_IGN) | - |
246 | { | - |
247 | struct sigaction newact; | - |
248 | | - |
249 | newact.sa_handler = sighandler; | - |
250 | sigemptyset (&newact.sa_mask); | - |
251 | newact.sa_flags = 0; | - |
252 | sigaction (SIGCONT, &newact, NULL); | - |
253 | } | - |
254 | initialized = true; | - |
255 | } | - |
256 | | - |
257 | suspended = 0; | - |
258 | | - |
259 | if (my_usleep (requested_delay) == -1) | - |
260 | { | - |
261 | if (suspended) | - |
262 | { | - |
263 | | - |
264 | | - |
265 | | - |
266 | | - |
267 | errno = EINTR; | - |
268 | } | - |
269 | return -1; | - |
270 | } | - |
271 | | - |
272 | | - |
273 | | - |
274 | return 0; | - |
275 | } | - |
276 | #endif | - |
| | |