• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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