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