xref: /netbsd-src/external/mit/libuv/dist/src/unix/signal.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
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 void uv__signal_cleanup(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_cleanup();
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   uv__signal_stop(handle);
335 }
336 
337 
338 int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
339   return uv__signal_start(handle, signal_cb, signum, 0);
340 }
341 
342 
343 int uv_signal_start_oneshot(uv_signal_t* handle,
344                             uv_signal_cb signal_cb,
345                             int signum) {
346   return uv__signal_start(handle, signal_cb, signum, 1);
347 }
348 
349 
350 static int uv__signal_start(uv_signal_t* handle,
351                             uv_signal_cb signal_cb,
352                             int signum,
353                             int oneshot) {
354   sigset_t saved_sigmask;
355   int err;
356   uv_signal_t* first_handle;
357 
358   assert(!uv__is_closing(handle));
359 
360   /* If the user supplies signum == 0, then return an error already. If the
361    * signum is otherwise invalid then uv__signal_register will find out
362    * eventually.
363    */
364   if (signum == 0)
365     return UV_EINVAL;
366 
367   /* Short circuit: if the signal watcher is already watching {signum} don't
368    * go through the process of deregistering and registering the handler.
369    * Additionally, this avoids pending signals getting lost in the small
370    * time frame that handle->signum == 0.
371    */
372   if (signum == handle->signum) {
373     handle->signal_cb = signal_cb;
374     return 0;
375   }
376 
377   /* If the signal handler was already active, stop it first. */
378   if (handle->signum != 0) {
379     uv__signal_stop(handle);
380   }
381 
382   uv__signal_block_and_lock(&saved_sigmask);
383 
384   /* If at this point there are no active signal watchers for this signum (in
385    * any of the loops), it's time to try and register a handler for it here.
386    * Also in case there's only one-shot handlers and a regular handler comes in.
387    */
388   first_handle = uv__signal_first_handle(signum);
389   if (first_handle == NULL ||
390       (!oneshot && (first_handle->flags & UV_SIGNAL_ONE_SHOT))) {
391     err = uv__signal_register_handler(signum, oneshot);
392     if (err) {
393       /* Registering the signal handler failed. Must be an invalid signal. */
394       uv__signal_unlock_and_unblock(&saved_sigmask);
395       return err;
396     }
397   }
398 
399   handle->signum = signum;
400   if (oneshot)
401     handle->flags |= UV_SIGNAL_ONE_SHOT;
402 
403   RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle);
404 
405   uv__signal_unlock_and_unblock(&saved_sigmask);
406 
407   handle->signal_cb = signal_cb;
408   uv__handle_start(handle);
409 
410   return 0;
411 }
412 
413 
414 static void uv__signal_event(uv_loop_t* loop,
415                              uv__io_t* w,
416                              unsigned int events) {
417   uv__signal_msg_t* msg;
418   uv_signal_t* handle;
419   char buf[sizeof(uv__signal_msg_t) * 32];
420   size_t bytes, end, i;
421   int r;
422 
423   bytes = 0;
424   end = 0;
425 
426   do {
427     r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
428 
429     if (r == -1 && errno == EINTR)
430       continue;
431 
432     if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
433       /* If there are bytes in the buffer already (which really is extremely
434        * unlikely if possible at all) we can't exit the function here. We'll
435        * spin until more bytes are read instead.
436        */
437       if (bytes > 0)
438         continue;
439 
440       /* Otherwise, there was nothing there. */
441       return;
442     }
443 
444     /* Other errors really should never happen. */
445     if (r == -1)
446       abort();
447 
448     bytes += r;
449 
450     /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */
451     end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t);
452 
453     for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) {
454       msg = (uv__signal_msg_t*) (buf + i);
455       handle = msg->handle;
456 
457       if (msg->signum == handle->signum) {
458         assert(!(handle->flags & UV_HANDLE_CLOSING));
459         handle->signal_cb(handle, handle->signum);
460       }
461 
462       handle->dispatched_signals++;
463 
464       if (handle->flags & UV_SIGNAL_ONE_SHOT)
465         uv__signal_stop(handle);
466     }
467 
468     bytes -= end;
469 
470     /* If there are any "partial" messages left, move them to the start of the
471      * the buffer, and spin. This should not happen.
472      */
473     if (bytes) {
474       memmove(buf, buf + end, bytes);
475       continue;
476     }
477   } while (end == sizeof buf);
478 }
479 
480 
481 static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
482   int f1;
483   int f2;
484   /* Compare signums first so all watchers with the same signnum end up
485    * adjacent.
486    */
487   if (w1->signum < w2->signum) return -1;
488   if (w1->signum > w2->signum) return 1;
489 
490   /* Handlers without UV_SIGNAL_ONE_SHOT set will come first, so if the first
491    * handler returned is a one-shot handler, the rest will be too.
492    */
493   f1 = w1->flags & UV_SIGNAL_ONE_SHOT;
494   f2 = w2->flags & UV_SIGNAL_ONE_SHOT;
495   if (f1 < f2) return -1;
496   if (f1 > f2) return 1;
497 
498   /* Sort by loop pointer, so we can easily look up the first item after
499    * { .signum = x, .loop = NULL }.
500    */
501   if (w1->loop < w2->loop) return -1;
502   if (w1->loop > w2->loop) return 1;
503 
504   if (w1 < w2) return -1;
505   if (w1 > w2) return 1;
506 
507   return 0;
508 }
509 
510 
511 int uv_signal_stop(uv_signal_t* handle) {
512   assert(!uv__is_closing(handle));
513   uv__signal_stop(handle);
514   return 0;
515 }
516 
517 
518 static void uv__signal_stop(uv_signal_t* handle) {
519   uv_signal_t* removed_handle;
520   sigset_t saved_sigmask;
521   uv_signal_t* first_handle;
522   int rem_oneshot;
523   int first_oneshot;
524   int ret;
525 
526   /* If the watcher wasn't started, this is a no-op. */
527   if (handle->signum == 0)
528     return;
529 
530   uv__signal_block_and_lock(&saved_sigmask);
531 
532   removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle);
533   assert(removed_handle == handle);
534   (void) removed_handle;
535 
536   /* Check if there are other active signal watchers observing this signal. If
537    * not, unregister the signal handler.
538    */
539   first_handle = uv__signal_first_handle(handle->signum);
540   if (first_handle == NULL) {
541     uv__signal_unregister_handler(handle->signum);
542   } else {
543     rem_oneshot = handle->flags & UV_SIGNAL_ONE_SHOT;
544     first_oneshot = first_handle->flags & UV_SIGNAL_ONE_SHOT;
545     if (first_oneshot && !rem_oneshot) {
546       ret = uv__signal_register_handler(handle->signum, 1);
547       assert(ret == 0);
548       (void)ret;
549     }
550   }
551 
552   uv__signal_unlock_and_unblock(&saved_sigmask);
553 
554   handle->signum = 0;
555   uv__handle_stop(handle);
556 }
557