Rizin
unix-like reverse engineering framework and cli tools
signal.c
Go to the documentation of this file.
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 {
37  int signum;
39 
40 RB_HEAD(uv__signal_tree_s, uv_signal_s);
41 
42 
43 static int uv__signal_unlock(void);
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);
50 static void uv__signal_stop(uv_signal_t* handle);
51 static void uv__signal_unregister_handler(int signum);
52 
53 
55 static struct uv__signal_tree_s 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,
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 
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) {
90  uv__signal_lock_pipefd[0] = -1;
91  }
92 
93  if (uv__signal_lock_pipefd[1] != -1) {
95  uv__signal_lock_pipefd[1] = -1;
96  }
97 }
98 
99 
100 static void uv__signal_global_reinit(void) {
102 
104  abort();
105 
106  if (uv__signal_unlock())
107  abort();
108 }
109 
110 
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  /* to shut up valgrind */
147  sigemptyset(saved_sigmask);
148  if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask))
149  abort();
150 
151  if (uv__signal_lock())
152  abort();
153 }
154 
155 
156 static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) {
157  if (uv__signal_unlock())
158  abort();
159 
160  if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL))
161  abort();
162 }
163 
164 
166  /* This function must be called with the signal lock held. */
167  uv_signal_t lookup;
169 
170  lookup.signum = signum;
171  lookup.flags = 0;
172  lookup.loop = NULL;
173 
174  handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup);
175 
176  if (handle != NULL && handle->signum == signum)
177  return handle;
178 
179  return NULL;
180 }
181 
182 
183 static void uv__signal_handler(int signum) {
186  int saved_errno;
187 
188  saved_errno = errno;
189  memset(&msg, 0, sizeof msg);
190 
191  if (uv__signal_lock()) {
192  errno = saved_errno;
193  return;
194  }
195 
197  handle != NULL && handle->signum == signum;
198  handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) {
199  int r;
200 
201  msg.signum = signum;
202  msg.handle = handle;
203 
204  /* write() should be atomic for small data chunks, so the entire message
205  * should be written at once. In theory the pipe could become full, in
206  * which case the user is out of luck.
207  */
208  do {
209  r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg);
210  } while (r == -1 && errno == EINTR);
211 
212  assert(r == sizeof msg ||
213  (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)));
214 
215  if (r != -1)
216  handle->caught_signals++;
217  }
218 
220  errno = saved_errno;
221 }
222 
223 
225  /* When this function is called, the signal lock must be held. */
226  struct sigaction sa;
227 
228  /* XXX use a separate signal stack? */
229  memset(&sa, 0, sizeof(sa));
230  if (sigfillset(&sa.sa_mask))
231  abort();
232  sa.sa_handler = uv__signal_handler;
233  sa.sa_flags = SA_RESTART;
234  if (oneshot)
235  sa.sa_flags |= SA_RESETHAND;
236 
237  /* XXX save old action so we can restore it later on? */
238  if (sigaction(signum, &sa, NULL))
239  return UV__ERR(errno);
240 
241  return 0;
242 }
243 
244 
246  /* When this function is called, the signal lock must be held. */
247  struct sigaction sa;
248 
249  memset(&sa, 0, sizeof(sa));
250  sa.sa_handler = SIG_DFL;
251 
252  /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a
253  * signal implies that it was successfully registered earlier, so EINVAL
254  * should never happen.
255  */
256  if (sigaction(signum, &sa, NULL))
257  abort();
258 }
259 
260 
262  int err;
263 
264  /* Return if already initialized. */
265  if (loop->signal_pipefd[0] != -1)
266  return 0;
267 
268  err = uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK);
269  if (err)
270  return err;
271 
272  uv__io_init(&loop->signal_io_watcher,
274  loop->signal_pipefd[0]);
275  uv__io_start(loop, &loop->signal_io_watcher, POLLIN);
276 
277  return 0;
278 }
279 
280 
282  uv__io_stop(loop, &loop->signal_io_watcher, POLLIN);
283  uv__close(loop->signal_pipefd[0]);
284  uv__close(loop->signal_pipefd[1]);
285  loop->signal_pipefd[0] = -1;
286  loop->signal_pipefd[1] = -1;
288 }
289 
290 
292  QUEUE* q;
293 
294  /* Stop all the signal watchers that are still attached to this loop. This
295  * ensures that the (shared) signal tree doesn't contain any invalid entries
296  * entries, and that signal handlers are removed when appropriate.
297  * It's safe to use QUEUE_FOREACH here because the handles and the handle
298  * queue are not modified by uv__signal_stop().
299  */
301  uv_handle_t* handle = QUEUE_DATA(q, uv_handle_t, handle_queue);
302 
303  if (handle->type == UV_SIGNAL)
305  }
306 
307  if (loop->signal_pipefd[0] != -1) {
308  uv__close(loop->signal_pipefd[0]);
309  loop->signal_pipefd[0] = -1;
310  }
311 
312  if (loop->signal_pipefd[1] != -1) {
313  uv__close(loop->signal_pipefd[1]);
314  loop->signal_pipefd[1] = -1;
315  }
316 }
317 
318 
320  int err;
321 
323  if (err)
324  return err;
325 
326  uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
327  handle->signum = 0;
328  handle->caught_signals = 0;
329  handle->dispatched_signals = 0;
330 
331  return 0;
332 }
333 
334 
337 }
338 
339 
341  return uv__signal_start(handle, signal_cb, signum, 0);
342 }
343 
344 
346  uv_signal_cb signal_cb,
347  int signum) {
348  return uv__signal_start(handle, signal_cb, signum, 1);
349 }
350 
351 
353  uv_signal_cb signal_cb,
354  int signum,
355  int oneshot) {
356  sigset_t saved_sigmask;
357  int err;
358  uv_signal_t* first_handle;
359 
361 
362  /* If the user supplies signum == 0, then return an error already. If the
363  * signum is otherwise invalid then uv__signal_register will find out
364  * eventually.
365  */
366  if (signum == 0)
367  return UV_EINVAL;
368 
369  /* Short circuit: if the signal watcher is already watching {signum} don't
370  * go through the process of deregistering and registering the handler.
371  * Additionally, this avoids pending signals getting lost in the small
372  * time frame that handle->signum == 0.
373  */
374  if (signum == handle->signum) {
375  handle->signal_cb = signal_cb;
376  return 0;
377  }
378 
379  /* If the signal handler was already active, stop it first. */
380  if (handle->signum != 0) {
382  }
383 
384  uv__signal_block_and_lock(&saved_sigmask);
385 
386  /* If at this point there are no active signal watchers for this signum (in
387  * any of the loops), it's time to try and register a handler for it here.
388  * Also in case there's only one-shot handlers and a regular handler comes in.
389  */
390  first_handle = uv__signal_first_handle(signum);
391  if (first_handle == NULL ||
392  (!oneshot && (first_handle->flags & UV_SIGNAL_ONE_SHOT))) {
394  if (err) {
395  /* Registering the signal handler failed. Must be an invalid signal. */
396  uv__signal_unlock_and_unblock(&saved_sigmask);
397  return err;
398  }
399  }
400 
401  handle->signum = signum;
402  if (oneshot)
403  handle->flags |= UV_SIGNAL_ONE_SHOT;
404 
405  RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle);
406 
407  uv__signal_unlock_and_unblock(&saved_sigmask);
408 
409  handle->signal_cb = signal_cb;
411 
412  return 0;
413 }
414 
415 
417  uv__io_t* w,
418  unsigned int events) {
421  char buf[sizeof(uv__signal_msg_t) * 32];
422  size_t bytes, end, i;
423  int r;
424 
425  bytes = 0;
426  end = 0;
427 
428  do {
429  r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
430 
431  if (r == -1 && errno == EINTR)
432  continue;
433 
434  if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
435  /* If there are bytes in the buffer already (which really is extremely
436  * unlikely if possible at all) we can't exit the function here. We'll
437  * spin until more bytes are read instead.
438  */
439  if (bytes > 0)
440  continue;
441 
442  /* Otherwise, there was nothing there. */
443  return;
444  }
445 
446  /* Other errors really should never happen. */
447  if (r == -1)
448  abort();
449 
450  bytes += r;
451 
452  /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */
453  end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t);
454 
455  for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) {
456  msg = (uv__signal_msg_t*) (buf + i);
457  handle = msg->handle;
458 
459  if (msg->signum == handle->signum) {
460  assert(!(handle->flags & UV_HANDLE_CLOSING));
461  handle->signal_cb(handle, handle->signum);
462  }
463 
464  handle->dispatched_signals++;
465 
466  if (handle->flags & UV_SIGNAL_ONE_SHOT)
468  }
469 
470  bytes -= end;
471 
472  /* If there are any "partial" messages left, move them to the start of the
473  * the buffer, and spin. This should not happen.
474  */
475  if (bytes) {
476  memmove(buf, buf + end, bytes);
477  continue;
478  }
479  } while (end == sizeof buf);
480 }
481 
482 
484  int f1;
485  int f2;
486  /* Compare signums first so all watchers with the same signnum end up
487  * adjacent.
488  */
489  if (w1->signum < w2->signum) return -1;
490  if (w1->signum > w2->signum) return 1;
491 
492  /* Handlers without UV_SIGNAL_ONE_SHOT set will come first, so if the first
493  * handler returned is a one-shot handler, the rest will be too.
494  */
495  f1 = w1->flags & UV_SIGNAL_ONE_SHOT;
496  f2 = w2->flags & UV_SIGNAL_ONE_SHOT;
497  if (f1 < f2) return -1;
498  if (f1 > f2) return 1;
499 
500  /* Sort by loop pointer, so we can easily look up the first item after
501  * { .signum = x, .loop = NULL }.
502  */
503  if (w1->loop < w2->loop) return -1;
504  if (w1->loop > w2->loop) return 1;
505 
506  if (w1 < w2) return -1;
507  if (w1 > w2) return 1;
508 
509  return 0;
510 }
511 
512 
516  return 0;
517 }
518 
519 
521  uv_signal_t* removed_handle;
522  sigset_t saved_sigmask;
523  uv_signal_t* first_handle;
524  int rem_oneshot;
525  int first_oneshot;
526  int ret;
527 
528  /* If the watcher wasn't started, this is a no-op. */
529  if (handle->signum == 0)
530  return;
531 
532  uv__signal_block_and_lock(&saved_sigmask);
533 
534  removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle);
535  assert(removed_handle == handle);
536  (void) removed_handle;
537 
538  /* Check if there are other active signal watchers observing this signal. If
539  * not, unregister the signal handler.
540  */
541  first_handle = uv__signal_first_handle(handle->signum);
542  if (first_handle == NULL) {
544  } else {
545  rem_oneshot = handle->flags & UV_SIGNAL_ONE_SHOT;
546  first_oneshot = first_handle->flags & UV_SIGNAL_ONE_SHOT;
547  if (first_oneshot && !rem_oneshot) {
548  ret = uv__signal_register_handler(handle->signum, 1);
549  assert(ret == 0);
550  (void)ret;
551  }
552  }
553 
554  uv__signal_unlock_and_unblock(&saved_sigmask);
555 
556  handle->signum = 0;
558 }
lzma_index ** i
Definition: index.h:629
static bool err
Definition: armass.c:435
static ut8 bytes[32]
Definition: asm_arc.c:23
static mcore_handle handle
Definition: asm_mcore.c:8
static RzBinXtrData * oneshot(RzBin *bin, const ut8 *buf, ut64 size, int subbin_type)
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
#define w
Definition: crypto_rc6.c:13
static static fork write
Definition: sflib.h:33
#define UV__ERR(x)
Definition: errno.h:29
voidpf void * buf
Definition: ioapi.h:138
return memset(p, 0, total)
#define RB_NEXT(name, x, y)
Definition: tree.h:731
#define RB_INSERT(name, x, y)
Definition: tree.h:727
#define RB_NFIND(name, x, y)
Definition: tree.h:730
#define RB_REMOVE(name, x, y)
Definition: tree.h:728
#define RB_INITIALIZER(root)
Definition: tree.h:301
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment signum
Definition: sflib.h:79
assert(limit<=UINT32_MAX/2)
#define QUEUE_FOREACH(q, h)
Definition: queue.h:36
#define QUEUE_DATA(ptr, type, field)
Definition: queue.h:30
void * QUEUE[2]
Definition: queue.h:21
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
#define EINTR
Definition: sftypes.h:114
#define EAGAIN
Definition: sftypes.h:121
int sigset_t
Definition: sftypes.h:63
Definition: unix.h:96
uv_signal_t * handle
Definition: signal.c:36
Definition: uv.h:1780
void * handle_queue[2]
Definition: uv.h:1785
int signum
Definition: uv.h:1577
uv_loop_t * loop
Definition: main.c:7
void uv__io_stop(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: core.c:910
void uv__io_start(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: core.c:882
void uv__io_init(uv__io_t *w, uv__io_cb cb, int fd)
Definition: core.c:865
int uv__close(int fd)
Definition: core.c:569
#define UV__F_NONBLOCK
Definition: internal.h:288
int uv__make_pipe(int fds[2], int flags)
Definition: process.c:142
static int uv__signal_loop_once_init(uv_loop_t *loop)
Definition: signal.c:261
int uv_signal_init(uv_loop_t *loop, uv_signal_t *handle)
Definition: signal.c:319
void uv__signal_loop_cleanup(uv_loop_t *loop)
Definition: signal.c:291
static int uv__signal_register_handler(int signum, int oneshot)
Definition: signal.c:224
RB_GENERATE_STATIC(uv__signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare)
Definition: signal.c:59
int uv__signal_loop_fork(uv_loop_t *loop)
Definition: signal.c:281
static void uv__signal_handler(int signum)
Definition: signal.c:183
static void uv__signal_stop(uv_signal_t *handle)
Definition: signal.c:520
static struct uv__signal_tree_s uv__signal_tree
Definition: signal.c:55
static int uv__signal_start(uv_signal_t *handle, uv_signal_cb signal_cb, int signum, int oneshot)
Definition: signal.c:352
void uv__signal_global_once_init(void)
Definition: signal.c:111
static void uv__signal_event(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: signal.c:416
static int uv__signal_compare(uv_signal_t *w1, uv_signal_t *w2)
Definition: signal.c:483
void uv__signal_close(uv_signal_t *handle)
Definition: signal.c:335
void uv__signal_cleanup(void)
Definition: signal.c:80
#define SA_RESTART
Definition: signal.c:32
int uv_signal_start_oneshot(uv_signal_t *handle, uv_signal_cb signal_cb, int signum)
Definition: signal.c:345
static void uv__signal_block_and_lock(sigset_t *saved_sigmask)
Definition: signal.c:140
static int uv__signal_unlock(void)
Definition: signal.c:128
static uv_signal_t * uv__signal_first_handle(int signum)
Definition: signal.c:165
RB_HEAD(uv__signal_tree_s, uv_signal_s)
static void uv__signal_unlock_and_unblock(sigset_t *saved_sigmask)
Definition: signal.c:156
static void uv__signal_global_reinit(void)
Definition: signal.c:100
static int uv__signal_lock_pipefd[2]
Definition: signal.c:57
int uv_signal_start(uv_signal_t *handle, uv_signal_cb signal_cb, int signum)
Definition: signal.c:340
static int uv__signal_lock(void)
Definition: signal.c:116
static void uv__signal_unregister_handler(int signum)
Definition: signal.c:245
int uv_signal_stop(uv_signal_t *handle)
Definition: signal.c:513
static uv_once_t uv__signal_global_init_guard
Definition: signal.c:54
pthread_once_t uv_once_t
Definition: unix.h:135
#define UV_ONCE_INIT
Definition: unix.h:133
@ UV_SIGNAL_ONE_SHOT
Definition: uv-common.h:129
@ UV_HANDLE_CLOSING
Definition: uv-common.h:74
#define uv__is_closing(h)
Definition: uv-common.h:255
#define uv__handle_init(loop_, h, type_)
Definition: uv-common.h:301
#define uv__handle_stop(h)
Definition: uv-common.h:266
#define uv__handle_start(h)
Definition: uv-common.h:258
UV_EXTERN void uv_once(uv_once_t *guard, void(*callback)(void))
Definition: thread.c:419
void(* uv_signal_cb)(uv_signal_t *handle, int signum)
Definition: uv.h:379
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115