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