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