1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. |
2 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
3 | * of this software and associated documentation files (the "Software"), to |
4 | * deal in the Software without restriction, including without limitation the |
5 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
6 | * sell copies of the Software, and to permit persons to whom the Software is |
7 | * furnished to do so, subject to the following conditions: |
8 | * |
9 | * The above copyright notice and this permission notice shall be included in |
10 | * all copies or substantial portions of the Software. |
11 | * |
12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
14 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
15 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
16 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
17 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
18 | * IN THE SOFTWARE. |
19 | */ |
20 | |
21 | #include "uv.h" |
22 | #include "internal.h" |
23 | |
24 | #include <assert.h> |
25 | #include <errno.h> |
26 | #include <signal.h> |
27 | #include <stdlib.h> |
28 | #include <string.h> |
29 | #include <unistd.h> |
30 | |
31 | #ifndef SA_RESTART |
32 | # define SA_RESTART 0 |
33 | #endif |
34 | |
35 | typedef struct { |
36 | uv_signal_t* handle; |
37 | int signum; |
38 | } uv__signal_msg_t; |
39 | |
40 | RB_HEAD(uv__signal_tree_s, uv_signal_s); |
41 | |
42 | |
43 | static int uv__signal_unlock(void); |
44 | static int uv__signal_start(uv_signal_t* handle, |
45 | uv_signal_cb signal_cb, |
46 | int signum, |
47 | int oneshot); |
48 | static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events); |
49 | static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); |
50 | static void uv__signal_stop(uv_signal_t* handle); |
51 | static void uv__signal_unregister_handler(int signum); |
52 | |
53 | |
54 | static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT; |
55 | static struct uv__signal_tree_s uv__signal_tree = |
56 | RB_INITIALIZER(uv__signal_tree); |
57 | static int uv__signal_lock_pipefd[2] = { -1, -1 }; |
58 | |
59 | RB_GENERATE_STATIC(uv__signal_tree_s, |
60 | uv_signal_s, tree_entry, |
61 | uv__signal_compare) |
62 | |
63 | static void uv__signal_global_reinit(void); |
64 | |
65 | static void uv__signal_global_init(void) { |
66 | if (uv__signal_lock_pipefd[0] == -1) |
67 | /* pthread_atfork can register before and after handlers, one |
68 | * for each child. This only registers one for the child. That |
69 | * state is both persistent and cumulative, so if we keep doing |
70 | * it the handler functions will be called multiple times. Thus |
71 | * we only want to do it once. |
72 | */ |
73 | if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit)) |
74 | abort(); |
75 | |
76 | uv__signal_global_reinit(); |
77 | } |
78 | |
79 | |
80 | UV_DESTRUCTOR(static void uv__signal_global_fini(void)) { |
81 | /* We can only use signal-safe functions here. |
82 | * That includes read/write and close, fortunately. |
83 | * We do all of this directly here instead of resetting |
84 | * uv__signal_global_init_guard because |
85 | * uv__signal_global_once_init is only called from uv_loop_init |
86 | * and this needs to function in existing loops. |
87 | */ |
88 | if (uv__signal_lock_pipefd[0] != -1) { |
89 | uv__close(uv__signal_lock_pipefd[0]); |
90 | uv__signal_lock_pipefd[0] = -1; |
91 | } |
92 | |
93 | if (uv__signal_lock_pipefd[1] != -1) { |
94 | uv__close(uv__signal_lock_pipefd[1]); |
95 | uv__signal_lock_pipefd[1] = -1; |
96 | } |
97 | } |
98 | |
99 | |
100 | static void uv__signal_global_reinit(void) { |
101 | uv__signal_global_fini(); |
102 | |
103 | if (uv__make_pipe(uv__signal_lock_pipefd, 0)) |
104 | abort(); |
105 | |
106 | if (uv__signal_unlock()) |
107 | abort(); |
108 | } |
109 | |
110 | |
111 | void uv__signal_global_once_init(void) { |
112 | uv_once(&uv__signal_global_init_guard, uv__signal_global_init); |
113 | } |
114 | |
115 | |
116 | static int uv__signal_lock(void) { |
117 | int r; |
118 | char data; |
119 | |
120 | do { |
121 | r = read(uv__signal_lock_pipefd[0], &data, sizeof data); |
122 | } while (r < 0 && errno == EINTR); |
123 | |
124 | return (r < 0) ? -1 : 0; |
125 | } |
126 | |
127 | |
128 | static int uv__signal_unlock(void) { |
129 | int r; |
130 | char data = 42; |
131 | |
132 | do { |
133 | r = write(uv__signal_lock_pipefd[1], &data, sizeof data); |
134 | } while (r < 0 && errno == EINTR); |
135 | |
136 | return (r < 0) ? -1 : 0; |
137 | } |
138 | |
139 | |
140 | static void uv__signal_block_and_lock(sigset_t* saved_sigmask) { |
141 | sigset_t new_mask; |
142 | |
143 | if (sigfillset(&new_mask)) |
144 | abort(); |
145 | |
146 | if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask)) |
147 | abort(); |
148 | |
149 | if (uv__signal_lock()) |
150 | abort(); |
151 | } |
152 | |
153 | |
154 | static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) { |
155 | if (uv__signal_unlock()) |
156 | abort(); |
157 | |
158 | if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL)) |
159 | abort(); |
160 | } |
161 | |
162 | |
163 | static uv_signal_t* uv__signal_first_handle(int signum) { |
164 | /* This function must be called with the signal lock held. */ |
165 | uv_signal_t lookup; |
166 | uv_signal_t* handle; |
167 | |
168 | lookup.signum = signum; |
169 | lookup.flags = 0; |
170 | lookup.loop = NULL; |
171 | |
172 | handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup); |
173 | |
174 | if (handle != NULL && handle->signum == signum) |
175 | return handle; |
176 | |
177 | return NULL; |
178 | } |
179 | |
180 | |
181 | static void uv__signal_handler(int signum) { |
182 | uv__signal_msg_t msg; |
183 | uv_signal_t* handle; |
184 | int saved_errno; |
185 | |
186 | saved_errno = errno; |
187 | memset(&msg, 0, sizeof msg); |
188 | |
189 | if (uv__signal_lock()) { |
190 | errno = saved_errno; |
191 | return; |
192 | } |
193 | |
194 | for (handle = uv__signal_first_handle(signum); |
195 | handle != NULL && handle->signum == signum; |
196 | handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) { |
197 | int r; |
198 | |
199 | msg.signum = signum; |
200 | msg.handle = handle; |
201 | |
202 | /* write() should be atomic for small data chunks, so the entire message |
203 | * should be written at once. In theory the pipe could become full, in |
204 | * which case the user is out of luck. |
205 | */ |
206 | do { |
207 | r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg); |
208 | } while (r == -1 && errno == EINTR); |
209 | |
210 | assert(r == sizeof msg || |
211 | (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))); |
212 | |
213 | if (r != -1) |
214 | handle->caught_signals++; |
215 | } |
216 | |
217 | uv__signal_unlock(); |
218 | errno = saved_errno; |
219 | } |
220 | |
221 | |
222 | static int uv__signal_register_handler(int signum, int oneshot) { |
223 | /* When this function is called, the signal lock must be held. */ |
224 | struct sigaction sa; |
225 | |
226 | /* XXX use a separate signal stack? */ |
227 | memset(&sa, 0, sizeof(sa)); |
228 | if (sigfillset(&sa.sa_mask)) |
229 | abort(); |
230 | sa.sa_handler = uv__signal_handler; |
231 | sa.sa_flags = SA_RESTART; |
232 | if (oneshot) |
233 | sa.sa_flags |= SA_RESETHAND; |
234 | |
235 | /* XXX save old action so we can restore it later on? */ |
236 | if (sigaction(signum, &sa, NULL)) |
237 | return UV__ERR(errno); |
238 | |
239 | return 0; |
240 | } |
241 | |
242 | |
243 | static void uv__signal_unregister_handler(int signum) { |
244 | /* When this function is called, the signal lock must be held. */ |
245 | struct sigaction sa; |
246 | |
247 | memset(&sa, 0, sizeof(sa)); |
248 | sa.sa_handler = SIG_DFL; |
249 | |
250 | /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a |
251 | * signal implies that it was successfully registered earlier, so EINVAL |
252 | * should never happen. |
253 | */ |
254 | if (sigaction(signum, &sa, NULL)) |
255 | abort(); |
256 | } |
257 | |
258 | |
259 | static int uv__signal_loop_once_init(uv_loop_t* loop) { |
260 | int err; |
261 | |
262 | /* Return if already initialized. */ |
263 | if (loop->signal_pipefd[0] != -1) |
264 | return 0; |
265 | |
266 | err = uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK); |
267 | if (err) |
268 | return err; |
269 | |
270 | uv__io_init(&loop->signal_io_watcher, |
271 | uv__signal_event, |
272 | loop->signal_pipefd[0]); |
273 | uv__io_start(loop, &loop->signal_io_watcher, POLLIN); |
274 | |
275 | return 0; |
276 | } |
277 | |
278 | |
279 | int uv__signal_loop_fork(uv_loop_t* loop) { |
280 | uv__io_stop(loop, &loop->signal_io_watcher, POLLIN); |
281 | uv__close(loop->signal_pipefd[0]); |
282 | uv__close(loop->signal_pipefd[1]); |
283 | loop->signal_pipefd[0] = -1; |
284 | loop->signal_pipefd[1] = -1; |
285 | return uv__signal_loop_once_init(loop); |
286 | } |
287 | |
288 | |
289 | void uv__signal_loop_cleanup(uv_loop_t* loop) { |
290 | QUEUE* q; |
291 | |
292 | /* Stop all the signal watchers that are still attached to this loop. This |
293 | * ensures that the (shared) signal tree doesn't contain any invalid entries |
294 | * entries, and that signal handlers are removed when appropriate. |
295 | * It's safe to use QUEUE_FOREACH here because the handles and the handle |
296 | * queue are not modified by uv__signal_stop(). |
297 | */ |
298 | QUEUE_FOREACH(q, &loop->handle_queue) { |
299 | uv_handle_t* handle = QUEUE_DATA(q, uv_handle_t, handle_queue); |
300 | |
301 | if (handle->type == UV_SIGNAL) |
302 | uv__signal_stop((uv_signal_t*) handle); |
303 | } |
304 | |
305 | if (loop->signal_pipefd[0] != -1) { |
306 | uv__close(loop->signal_pipefd[0]); |
307 | loop->signal_pipefd[0] = -1; |
308 | } |
309 | |
310 | if (loop->signal_pipefd[1] != -1) { |
311 | uv__close(loop->signal_pipefd[1]); |
312 | loop->signal_pipefd[1] = -1; |
313 | } |
314 | } |
315 | |
316 | |
317 | int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { |
318 | int err; |
319 | |
320 | err = uv__signal_loop_once_init(loop); |
321 | if (err) |
322 | return err; |
323 | |
324 | uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); |
325 | handle->signum = 0; |
326 | handle->caught_signals = 0; |
327 | handle->dispatched_signals = 0; |
328 | |
329 | return 0; |
330 | } |
331 | |
332 | |
333 | void uv__signal_close(uv_signal_t* handle) { |
334 | |
335 | uv__signal_stop(handle); |
336 | |
337 | /* If there are any caught signals "trapped" in the signal pipe, we can't |
338 | * call the close callback yet. Otherwise, add the handle to the finish_close |
339 | * queue. |
340 | */ |
341 | if (handle->caught_signals == handle->dispatched_signals) { |
342 | uv__make_close_pending((uv_handle_t*) handle); |
343 | } |
344 | } |
345 | |
346 | |
347 | int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { |
348 | return uv__signal_start(handle, signal_cb, signum, 0); |
349 | } |
350 | |
351 | |
352 | int uv_signal_start_oneshot(uv_signal_t* handle, |
353 | uv_signal_cb signal_cb, |
354 | int signum) { |
355 | return uv__signal_start(handle, signal_cb, signum, 1); |
356 | } |
357 | |
358 | |
359 | static int uv__signal_start(uv_signal_t* handle, |
360 | uv_signal_cb signal_cb, |
361 | int signum, |
362 | int oneshot) { |
363 | sigset_t saved_sigmask; |
364 | int err; |
365 | uv_signal_t* first_handle; |
366 | |
367 | assert(!uv__is_closing(handle)); |
368 | |
369 | /* If the user supplies signum == 0, then return an error already. If the |
370 | * signum is otherwise invalid then uv__signal_register will find out |
371 | * eventually. |
372 | */ |
373 | if (signum == 0) |
374 | return UV_EINVAL; |
375 | |
376 | /* Short circuit: if the signal watcher is already watching {signum} don't |
377 | * go through the process of deregistering and registering the handler. |
378 | * Additionally, this avoids pending signals getting lost in the small |
379 | * time frame that handle->signum == 0. |
380 | */ |
381 | if (signum == handle->signum) { |
382 | handle->signal_cb = signal_cb; |
383 | return 0; |
384 | } |
385 | |
386 | /* If the signal handler was already active, stop it first. */ |
387 | if (handle->signum != 0) { |
388 | uv__signal_stop(handle); |
389 | } |
390 | |
391 | uv__signal_block_and_lock(&saved_sigmask); |
392 | |
393 | /* If at this point there are no active signal watchers for this signum (in |
394 | * any of the loops), it's time to try and register a handler for it here. |
395 | * Also in case there's only one-shot handlers and a regular handler comes in. |
396 | */ |
397 | first_handle = uv__signal_first_handle(signum); |
398 | if (first_handle == NULL || |
399 | (!oneshot && (first_handle->flags & UV_SIGNAL_ONE_SHOT))) { |
400 | err = uv__signal_register_handler(signum, oneshot); |
401 | if (err) { |
402 | /* Registering the signal handler failed. Must be an invalid signal. */ |
403 | uv__signal_unlock_and_unblock(&saved_sigmask); |
404 | return err; |
405 | } |
406 | } |
407 | |
408 | handle->signum = signum; |
409 | if (oneshot) |
410 | handle->flags |= UV_SIGNAL_ONE_SHOT; |
411 | |
412 | RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle); |
413 | |
414 | uv__signal_unlock_and_unblock(&saved_sigmask); |
415 | |
416 | handle->signal_cb = signal_cb; |
417 | uv__handle_start(handle); |
418 | |
419 | return 0; |
420 | } |
421 | |
422 | |
423 | static void uv__signal_event(uv_loop_t* loop, |
424 | uv__io_t* w, |
425 | unsigned int events) { |
426 | uv__signal_msg_t* msg; |
427 | uv_signal_t* handle; |
428 | char buf[sizeof(uv__signal_msg_t) * 32]; |
429 | size_t bytes, end, i; |
430 | int r; |
431 | |
432 | bytes = 0; |
433 | end = 0; |
434 | |
435 | do { |
436 | r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes); |
437 | |
438 | if (r == -1 && errno == EINTR) |
439 | continue; |
440 | |
441 | if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { |
442 | /* If there are bytes in the buffer already (which really is extremely |
443 | * unlikely if possible at all) we can't exit the function here. We'll |
444 | * spin until more bytes are read instead. |
445 | */ |
446 | if (bytes > 0) |
447 | continue; |
448 | |
449 | /* Otherwise, there was nothing there. */ |
450 | return; |
451 | } |
452 | |
453 | /* Other errors really should never happen. */ |
454 | if (r == -1) |
455 | abort(); |
456 | |
457 | bytes += r; |
458 | |
459 | /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */ |
460 | end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t); |
461 | |
462 | for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) { |
463 | msg = (uv__signal_msg_t*) (buf + i); |
464 | handle = msg->handle; |
465 | |
466 | if (msg->signum == handle->signum) { |
467 | assert(!(handle->flags & UV_HANDLE_CLOSING)); |
468 | handle->signal_cb(handle, handle->signum); |
469 | } |
470 | |
471 | handle->dispatched_signals++; |
472 | |
473 | if (handle->flags & UV_SIGNAL_ONE_SHOT) |
474 | uv__signal_stop(handle); |
475 | |
476 | /* If uv_close was called while there were caught signals that were not |
477 | * yet dispatched, the uv__finish_close was deferred. Make close pending |
478 | * now if this has happened. |
479 | */ |
480 | if ((handle->flags & UV_HANDLE_CLOSING) && |
481 | (handle->caught_signals == handle->dispatched_signals)) { |
482 | uv__make_close_pending((uv_handle_t*) handle); |
483 | } |
484 | } |
485 | |
486 | bytes -= end; |
487 | |
488 | /* If there are any "partial" messages left, move them to the start of the |
489 | * the buffer, and spin. This should not happen. |
490 | */ |
491 | if (bytes) { |
492 | memmove(buf, buf + end, bytes); |
493 | continue; |
494 | } |
495 | } while (end == sizeof buf); |
496 | } |
497 | |
498 | |
499 | static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { |
500 | int f1; |
501 | int f2; |
502 | /* Compare signums first so all watchers with the same signnum end up |
503 | * adjacent. |
504 | */ |
505 | if (w1->signum < w2->signum) return -1; |
506 | if (w1->signum > w2->signum) return 1; |
507 | |
508 | /* Handlers without UV_SIGNAL_ONE_SHOT set will come first, so if the first |
509 | * handler returned is a one-shot handler, the rest will be too. |
510 | */ |
511 | f1 = w1->flags & UV_SIGNAL_ONE_SHOT; |
512 | f2 = w2->flags & UV_SIGNAL_ONE_SHOT; |
513 | if (f1 < f2) return -1; |
514 | if (f1 > f2) return 1; |
515 | |
516 | /* Sort by loop pointer, so we can easily look up the first item after |
517 | * { .signum = x, .loop = NULL }. |
518 | */ |
519 | if (w1->loop < w2->loop) return -1; |
520 | if (w1->loop > w2->loop) return 1; |
521 | |
522 | if (w1 < w2) return -1; |
523 | if (w1 > w2) return 1; |
524 | |
525 | return 0; |
526 | } |
527 | |
528 | |
529 | int uv_signal_stop(uv_signal_t* handle) { |
530 | assert(!uv__is_closing(handle)); |
531 | uv__signal_stop(handle); |
532 | return 0; |
533 | } |
534 | |
535 | |
536 | static void uv__signal_stop(uv_signal_t* handle) { |
537 | uv_signal_t* removed_handle; |
538 | sigset_t saved_sigmask; |
539 | uv_signal_t* first_handle; |
540 | int rem_oneshot; |
541 | int first_oneshot; |
542 | int ret; |
543 | |
544 | /* If the watcher wasn't started, this is a no-op. */ |
545 | if (handle->signum == 0) |
546 | return; |
547 | |
548 | uv__signal_block_and_lock(&saved_sigmask); |
549 | |
550 | removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle); |
551 | assert(removed_handle == handle); |
552 | (void) removed_handle; |
553 | |
554 | /* Check if there are other active signal watchers observing this signal. If |
555 | * not, unregister the signal handler. |
556 | */ |
557 | first_handle = uv__signal_first_handle(handle->signum); |
558 | if (first_handle == NULL) { |
559 | uv__signal_unregister_handler(handle->signum); |
560 | } else { |
561 | rem_oneshot = handle->flags & UV_SIGNAL_ONE_SHOT; |
562 | first_oneshot = first_handle->flags & UV_SIGNAL_ONE_SHOT; |
563 | if (first_oneshot && !rem_oneshot) { |
564 | ret = uv__signal_register_handler(handle->signum, 1); |
565 | assert(ret == 0); |
566 | } |
567 | } |
568 | |
569 | uv__signal_unlock_and_unblock(&saved_sigmask); |
570 | |
571 | handle->signum = 0; |
572 | uv__handle_stop(handle); |
573 | } |
574 | |