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