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