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
36 typedef struct {
37 uv_signal_t* handle;
38 int signum;
39 } uv__signal_msg_t;
40
41 RB_HEAD(uv__signal_tree_s, uv_signal_s);
42
43
44 static int uv__signal_unlock(void);
45 static int uv__signal_start(uv_signal_t* handle,
46 uv_signal_cb signal_cb,
47 int signum,
48 int oneshot);
49 static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
50 static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
51 static void uv__signal_stop(uv_signal_t* handle);
52 static void uv__signal_unregister_handler(int signum);
53
54
55 static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT;
56 static struct uv__signal_tree_s uv__signal_tree =
57 RB_INITIALIZER(uv__signal_tree);
58 static int uv__signal_lock_pipefd[2] = { -1, -1 };
59
60 RB_GENERATE_STATIC(uv__signal_tree_s,
61 uv_signal_s, tree_entry,
62 uv__signal_compare)
63
64 static void uv__signal_global_reinit(void);
65
uv__signal_global_init(void)66 static 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
uv__signal_cleanup(void)81 void 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
uv__signal_global_reinit(void)101 static 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
uv__signal_global_once_init(void)118 void uv__signal_global_once_init(void) {
119 uv_once(&uv__signal_global_init_guard, uv__signal_global_init);
120 }
121
122
uv__signal_lock(void)123 static 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
uv__signal_unlock(void)135 static 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
uv__signal_block_and_lock(sigset_t* saved_sigmask)147 static 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
uv__signal_unlock_and_unblock(sigset_t* saved_sigmask)169 static 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
uv__signal_first_handle(int signum)184 static 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
uv__signal_handler(int signum)202 static 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
uv__signal_register_handler(int signum, int oneshot)243 static 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
uv__signal_unregister_handler(int signum)264 static 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
uv__signal_loop_once_init(uv_loop_t* loop)280 static 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
uv__signal_loop_fork(uv_loop_t* loop)300 int 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
uv__signal_loop_cleanup(uv_loop_t* loop)327 void 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
uv_signal_init(uv_loop_t* loop, uv_signal_t* handle)355 int 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
uv__signal_close(uv_signal_t* handle)371 void uv__signal_close(uv_signal_t* handle) {
372 uv__signal_stop(handle);
373 }
374
375
uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum)376 int 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
uv_signal_start_oneshot(uv_signal_t* handle, uv_signal_cb signal_cb, int signum)381 int 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
uv__signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum, int oneshot)388 static 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
uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events)452 static 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
uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2)525 static 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
uv_signal_stop(uv_signal_t* handle)555 int uv_signal_stop(uv_signal_t* handle) {
556 assert(!uv__is_closing(handle));
557 uv__signal_stop(handle);
558 return 0;
559 }
560
561
uv__signal_stop(uv_signal_t* handle)562 static 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