1/********************************************************************** 2 3 signal.c - 4 5 $Author: nagachika $ 6 created at: Tue Dec 20 10:13:44 JST 1994 7 8 Copyright (C) 1993-2007 Yukihiro Matsumoto 9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc. 10 Copyright (C) 2000 Information-technology Promotion Agency, Japan 11 12**********************************************************************/ 13 14#include "ruby/ruby.h" 15#include "vm_core.h" 16#include <signal.h> 17#include <stdio.h> 18#include <errno.h> 19#include "ruby_atomic.h" 20#include "eval_intern.h" 21 22#if defined(__native_client__) && defined(NACL_NEWLIB) 23# include "nacl/signal.h" 24#endif 25 26#ifdef NEED_RUBY_ATOMIC_OPS 27rb_atomic_t 28ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val) 29{ 30 rb_atomic_t old = *ptr; 31 *ptr = val; 32 return old; 33} 34 35rb_atomic_t 36ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp, 37 rb_atomic_t newval) 38{ 39 rb_atomic_t old = *ptr; 40 if (old == cmp) { 41 *ptr = newval; 42 } 43 return old; 44} 45#endif 46 47#if defined(__BEOS__) || defined(__HAIKU__) 48#undef SIGBUS 49#endif 50 51#ifndef NSIG 52# define NSIG (_SIGMAX + 1) /* For QNX */ 53#endif 54 55static const struct signals { 56 const char *signm; 57 int signo; 58} siglist [] = { 59 {"EXIT", 0}, 60#ifdef SIGHUP 61 {"HUP", SIGHUP}, 62#endif 63 {"INT", SIGINT}, 64#ifdef SIGQUIT 65 {"QUIT", SIGQUIT}, 66#endif 67#ifdef SIGILL 68 {"ILL", SIGILL}, 69#endif 70#ifdef SIGTRAP 71 {"TRAP", SIGTRAP}, 72#endif 73#ifdef SIGIOT 74 {"IOT", SIGIOT}, 75#endif 76#ifdef SIGABRT 77 {"ABRT", SIGABRT}, 78#endif 79#ifdef SIGEMT 80 {"EMT", SIGEMT}, 81#endif 82#ifdef SIGFPE 83 {"FPE", SIGFPE}, 84#endif 85#ifdef SIGKILL 86 {"KILL", SIGKILL}, 87#endif 88#ifdef SIGBUS 89 {"BUS", SIGBUS}, 90#endif 91#ifdef SIGSEGV 92 {"SEGV", SIGSEGV}, 93#endif 94#ifdef SIGSYS 95 {"SYS", SIGSYS}, 96#endif 97#ifdef SIGPIPE 98 {"PIPE", SIGPIPE}, 99#endif 100#ifdef SIGALRM 101 {"ALRM", SIGALRM}, 102#endif 103#ifdef SIGTERM 104 {"TERM", SIGTERM}, 105#endif 106#ifdef SIGURG 107 {"URG", SIGURG}, 108#endif 109#ifdef SIGSTOP 110 {"STOP", SIGSTOP}, 111#endif 112#ifdef SIGTSTP 113 {"TSTP", SIGTSTP}, 114#endif 115#ifdef SIGCONT 116 {"CONT", SIGCONT}, 117#endif 118#ifdef SIGCHLD 119 {"CHLD", SIGCHLD}, 120#endif 121#ifdef SIGCLD 122 {"CLD", SIGCLD}, 123#else 124# ifdef SIGCHLD 125 {"CLD", SIGCHLD}, 126# endif 127#endif 128#ifdef SIGTTIN 129 {"TTIN", SIGTTIN}, 130#endif 131#ifdef SIGTTOU 132 {"TTOU", SIGTTOU}, 133#endif 134#ifdef SIGIO 135 {"IO", SIGIO}, 136#endif 137#ifdef SIGXCPU 138 {"XCPU", SIGXCPU}, 139#endif 140#ifdef SIGXFSZ 141 {"XFSZ", SIGXFSZ}, 142#endif 143#ifdef SIGVTALRM 144 {"VTALRM", SIGVTALRM}, 145#endif 146#ifdef SIGPROF 147 {"PROF", SIGPROF}, 148#endif 149#ifdef SIGWINCH 150 {"WINCH", SIGWINCH}, 151#endif 152#ifdef SIGUSR1 153 {"USR1", SIGUSR1}, 154#endif 155#ifdef SIGUSR2 156 {"USR2", SIGUSR2}, 157#endif 158#ifdef SIGLOST 159 {"LOST", SIGLOST}, 160#endif 161#ifdef SIGMSG 162 {"MSG", SIGMSG}, 163#endif 164#ifdef SIGPWR 165 {"PWR", SIGPWR}, 166#endif 167#ifdef SIGPOLL 168 {"POLL", SIGPOLL}, 169#endif 170#ifdef SIGDANGER 171 {"DANGER", SIGDANGER}, 172#endif 173#ifdef SIGMIGRATE 174 {"MIGRATE", SIGMIGRATE}, 175#endif 176#ifdef SIGPRE 177 {"PRE", SIGPRE}, 178#endif 179#ifdef SIGGRANT 180 {"GRANT", SIGGRANT}, 181#endif 182#ifdef SIGRETRACT 183 {"RETRACT", SIGRETRACT}, 184#endif 185#ifdef SIGSOUND 186 {"SOUND", SIGSOUND}, 187#endif 188#ifdef SIGINFO 189 {"INFO", SIGINFO}, 190#endif 191 {NULL, 0} 192}; 193 194static int 195signm2signo(const char *nm) 196{ 197 const struct signals *sigs; 198 199 for (sigs = siglist; sigs->signm; sigs++) 200 if (strcmp(sigs->signm, nm) == 0) 201 return sigs->signo; 202 return 0; 203} 204 205static const char* 206signo2signm(int no) 207{ 208 const struct signals *sigs; 209 210 for (sigs = siglist; sigs->signm; sigs++) 211 if (sigs->signo == no) 212 return sigs->signm; 213 return 0; 214} 215 216/* 217 * call-seq: 218 * Signal.signame(signo) -> string 219 * 220 * convert signal number to signal name 221 * 222 * Signal.trap("INT") { |signo| puts Signal.signame(signo) } 223 * Process.kill("INT", 0) 224 * 225 * <em>produces:</em> 226 * 227 * INT 228 */ 229static VALUE 230sig_signame(VALUE recv, VALUE signo) 231{ 232 const char *signame = signo2signm(NUM2INT(signo)); 233 return rb_str_new_cstr(signame); 234} 235 236const char * 237ruby_signal_name(int no) 238{ 239 return signo2signm(no); 240} 241 242/* 243 * call-seq: 244 * SignalException.new(sig_name) -> signal_exception 245 * SignalException.new(sig_number [, name]) -> signal_exception 246 * 247 * Construct a new SignalException object. +sig_name+ should be a known 248 * signal name. 249 */ 250 251static VALUE 252esignal_init(int argc, VALUE *argv, VALUE self) 253{ 254 int argnum = 1; 255 VALUE sig = Qnil; 256 int signo; 257 const char *signm; 258 259 if (argc > 0) { 260 sig = rb_check_to_integer(argv[0], "to_int"); 261 if (!NIL_P(sig)) argnum = 2; 262 else sig = argv[0]; 263 } 264 rb_check_arity(argc, 1, argnum); 265 if (argnum == 2) { 266 signo = NUM2INT(sig); 267 if (signo < 0 || signo > NSIG) { 268 rb_raise(rb_eArgError, "invalid signal number (%d)", signo); 269 } 270 if (argc > 1) { 271 sig = argv[1]; 272 } 273 else { 274 signm = signo2signm(signo); 275 if (signm) { 276 sig = rb_sprintf("SIG%s", signm); 277 } 278 else { 279 sig = rb_sprintf("SIG%u", signo); 280 } 281 } 282 } 283 else { 284 signm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig); 285 if (strncmp(signm, "SIG", 3) == 0) signm += 3; 286 signo = signm2signo(signm); 287 if (!signo) { 288 rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm); 289 } 290 sig = rb_sprintf("SIG%s", signm); 291 } 292 rb_call_super(1, &sig); 293 rb_iv_set(self, "signo", INT2NUM(signo)); 294 295 return self; 296} 297 298/* 299 * call-seq: 300 * signal_exception.signo -> num 301 * 302 * Returns a signal number. 303 */ 304 305static VALUE 306esignal_signo(VALUE self) 307{ 308 return rb_iv_get(self, "signo"); 309} 310 311/* :nodoc: */ 312static VALUE 313interrupt_init(int argc, VALUE *argv, VALUE self) 314{ 315 VALUE args[2]; 316 317 args[0] = INT2FIX(SIGINT); 318 rb_scan_args(argc, argv, "01", &args[1]); 319 return rb_call_super(2, args); 320} 321 322void 323ruby_default_signal(int sig) 324{ 325 signal(sig, SIG_DFL); 326 raise(sig); 327} 328 329/* 330 * call-seq: 331 * Process.kill(signal, pid, ...) -> fixnum 332 * 333 * Sends the given signal to the specified process id(s) if _pid_ is positive. 334 * If _pid_ is zero _signal_ is sent to all processes whose group ID is equal 335 * to the group ID of the process. _signal_ may be an integer signal number or 336 * a POSIX signal name (either with or without a +SIG+ prefix). If _signal_ is 337 * negative (or starts with a minus sign), kills process groups instead of 338 * processes. Not all signals are available on all platforms. 339 * 340 * pid = fork do 341 * Signal.trap("HUP") { puts "Ouch!"; exit } 342 * # ... do some work ... 343 * end 344 * # ... 345 * Process.kill("HUP", pid) 346 * Process.wait 347 * 348 * <em>produces:</em> 349 * 350 * Ouch! 351 * 352 * If _signal_ is an integer but wrong for signal, 353 * <code>Errno::EINVAL</code> or +RangeError+ will be raised. 354 * Otherwise unless _signal_ is a +String+ or a +Symbol+, and a known 355 * signal name, +ArgumentError+ will be raised. 356 * 357 * Also, <code>Errno::ESRCH</code> or +RangeError+ for invalid _pid_, 358 * <code>Errno::EPERM</code> when failed because of no privilege, 359 * will be raised. In these cases, signals may have been sent to 360 * preceding processes. 361 */ 362 363VALUE 364rb_f_kill(int argc, VALUE *argv) 365{ 366#ifndef HAVE_KILLPG 367#define killpg(pg, sig) kill(-(pg), (sig)) 368#endif 369 int negative = 0; 370 int sig; 371 int i; 372 volatile VALUE str; 373 const char *s; 374 375 rb_secure(2); 376 rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS); 377 378 switch (TYPE(argv[0])) { 379 case T_FIXNUM: 380 sig = FIX2INT(argv[0]); 381 break; 382 383 case T_SYMBOL: 384 s = rb_id2name(SYM2ID(argv[0])); 385 if (!s) rb_raise(rb_eArgError, "bad signal"); 386 goto str_signal; 387 388 case T_STRING: 389 s = RSTRING_PTR(argv[0]); 390 str_signal: 391 if (s[0] == '-') { 392 negative++; 393 s++; 394 } 395 if (strncmp("SIG", s, 3) == 0) 396 s += 3; 397 if ((sig = signm2signo(s)) == 0) 398 rb_raise(rb_eArgError, "unsupported name `SIG%s'", s); 399 400 if (negative) 401 sig = -sig; 402 break; 403 404 default: 405 str = rb_check_string_type(argv[0]); 406 if (!NIL_P(str)) { 407 s = RSTRING_PTR(str); 408 goto str_signal; 409 } 410 rb_raise(rb_eArgError, "bad signal type %s", 411 rb_obj_classname(argv[0])); 412 break; 413 } 414 415 if (sig < 0) { 416 sig = -sig; 417 for (i=1; i<argc; i++) { 418 if (killpg(NUM2PIDT(argv[i]), sig) < 0) 419 rb_sys_fail(0); 420 } 421 } 422 else { 423 for (i=1; i<argc; i++) { 424 if (kill(NUM2PIDT(argv[i]), sig) < 0) 425 rb_sys_fail(0); 426 } 427 } 428 return INT2FIX(i-1); 429} 430 431static struct { 432 rb_atomic_t cnt[RUBY_NSIG]; 433 rb_atomic_t size; 434} signal_buff; 435 436#ifdef __dietlibc__ 437#define sighandler_t sh_t 438#endif 439 440typedef RETSIGTYPE (*sighandler_t)(int); 441#ifdef USE_SIGALTSTACK 442typedef void ruby_sigaction_t(int, siginfo_t*, void*); 443#define SIGINFO_ARG , siginfo_t *info, void *ctx 444#else 445typedef RETSIGTYPE ruby_sigaction_t(int); 446#define SIGINFO_ARG 447#endif 448 449#ifdef USE_SIGALTSTACK 450int rb_sigaltstack_size(void) 451{ 452 /* XXX: BSD_vfprintf() uses >1500KiB stack and x86-64 need >5KiB stack. */ 453 int size = 8192; 454 455#ifdef MINSIGSTKSZ 456 if (size < MINSIGSTKSZ) 457 size = MINSIGSTKSZ; 458#endif 459#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) 460 { 461 int pagesize; 462 pagesize = (int)sysconf(_SC_PAGE_SIZE); 463 if (size < pagesize) 464 size = pagesize; 465 } 466#endif 467 468 return size; 469} 470 471/* alternate stack for SIGSEGV */ 472void 473rb_register_sigaltstack(rb_thread_t *th) 474{ 475 stack_t newSS, oldSS; 476 477 if (!th->altstack) 478 rb_bug("rb_register_sigaltstack: th->altstack not initialized\n"); 479 480 newSS.ss_sp = th->altstack; 481 newSS.ss_size = rb_sigaltstack_size(); 482 newSS.ss_flags = 0; 483 484 sigaltstack(&newSS, &oldSS); /* ignore error. */ 485} 486#endif /* USE_SIGALTSTACK */ 487 488#ifdef POSIX_SIGNAL 489static sighandler_t 490ruby_signal(int signum, sighandler_t handler) 491{ 492 struct sigaction sigact, old; 493 494#if 0 495 rb_trap_accept_nativethreads[signum] = 0; 496#endif 497 498 sigemptyset(&sigact.sa_mask); 499#ifdef USE_SIGALTSTACK 500 sigact.sa_sigaction = (ruby_sigaction_t*)handler; 501 sigact.sa_flags = SA_SIGINFO; 502#else 503 sigact.sa_handler = handler; 504 sigact.sa_flags = 0; 505#endif 506 507#ifdef SA_NOCLDWAIT 508 if (signum == SIGCHLD && handler == SIG_IGN) 509 sigact.sa_flags |= SA_NOCLDWAIT; 510#endif 511#if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK) 512 if (signum == SIGSEGV 513#ifdef SIGBUS 514 || signum == SIGBUS 515#endif 516 ) 517 sigact.sa_flags |= SA_ONSTACK; 518#endif 519 if (sigaction(signum, &sigact, &old) < 0) { 520 if (errno != 0 && errno != EINVAL) { 521 rb_bug_errno("sigaction", errno); 522 } 523 } 524 return old.sa_handler; 525} 526 527sighandler_t 528posix_signal(int signum, sighandler_t handler) 529{ 530 return ruby_signal(signum, handler); 531} 532 533#else /* !POSIX_SIGNAL */ 534#define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler))) 535#if 0 /* def HAVE_NATIVETHREAD */ 536static sighandler_t 537ruby_nativethread_signal(int signum, sighandler_t handler) 538{ 539 sighandler_t old; 540 541 old = signal(signum, handler); 542 rb_trap_accept_nativethreads[signum] = 1; 543 return old; 544} 545#endif 546#endif 547 548static RETSIGTYPE 549sighandler(int sig) 550{ 551 ATOMIC_INC(signal_buff.cnt[sig]); 552 ATOMIC_INC(signal_buff.size); 553 rb_thread_wakeup_timer_thread(); 554#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) 555 ruby_signal(sig, sighandler); 556#endif 557} 558 559int 560rb_signal_buff_size(void) 561{ 562 return signal_buff.size; 563} 564 565#if HAVE_PTHREAD_H 566#include <pthread.h> 567#endif 568 569static void 570rb_disable_interrupt(void) 571{ 572#ifdef HAVE_PTHREAD_SIGMASK 573 sigset_t mask; 574 sigfillset(&mask); 575 pthread_sigmask(SIG_SETMASK, &mask, NULL); 576#endif 577} 578 579static void 580rb_enable_interrupt(void) 581{ 582#ifdef HAVE_PTHREAD_SIGMASK 583 sigset_t mask; 584 sigemptyset(&mask); 585 pthread_sigmask(SIG_SETMASK, &mask, NULL); 586#endif 587} 588 589int 590rb_get_next_signal(void) 591{ 592 int i, sig = 0; 593 594 if (signal_buff.size != 0) { 595 for (i=1; i<RUBY_NSIG; i++) { 596 if (signal_buff.cnt[i] > 0) { 597 ATOMIC_DEC(signal_buff.cnt[i]); 598 ATOMIC_DEC(signal_buff.size); 599 sig = i; 600 break; 601 } 602 } 603 } 604 return sig; 605} 606 607 608#ifdef USE_SIGALTSTACK 609static void 610check_stack_overflow(const void *addr) 611{ 612 int ruby_stack_overflowed_p(const rb_thread_t *, const void *); 613 NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); 614 rb_thread_t *th = GET_THREAD(); 615 if (ruby_stack_overflowed_p(th, addr)) { 616 ruby_thread_stack_overflow(th); 617 } 618} 619#define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr) 620#else 621#define CHECK_STACK_OVERFLOW() (void)0 622#endif 623 624#ifdef SIGBUS 625static RETSIGTYPE 626sigbus(int sig SIGINFO_ARG) 627{ 628/* 629 * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page. 630 * and it's delivered as SIGBUS instaed of SIGSEGV to userland. It's crazy 631 * wrong IMHO. but anyway we have to care it. Sigh. 632 */ 633#if defined __APPLE__ 634 CHECK_STACK_OVERFLOW(); 635#endif 636 rb_bug("Bus Error"); 637} 638#endif 639 640#ifdef SIGSEGV 641static void ruby_abort(void) 642{ 643#ifdef __sun 644 /* Solaris's abort() is async signal unsafe. Of course, it is not 645 * POSIX compliant. 646 */ 647 raise(SIGABRT); 648#else 649 abort(); 650#endif 651 652} 653 654static int segv_received = 0; 655extern int ruby_disable_gc_stress; 656 657static RETSIGTYPE 658sigsegv(int sig SIGINFO_ARG) 659{ 660 if (segv_received) { 661 ssize_t RB_UNUSED_VAR(err); 662 char msg[] = "SEGV received in SEGV handler\n"; 663 664 err = write(2, msg, sizeof(msg)); 665 ruby_abort(); 666 } 667 668 CHECK_STACK_OVERFLOW(); 669 670 segv_received = 1; 671 ruby_disable_gc_stress = 1; 672 rb_bug("Segmentation fault"); 673} 674#endif 675 676static void 677signal_exec(VALUE cmd, int safe, int sig) 678{ 679 rb_thread_t *cur_th = GET_THREAD(); 680 volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask; 681 int state; 682 683 cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK; 684 TH_PUSH_TAG(cur_th); 685 if ((state = EXEC_TAG()) == 0) { 686 VALUE signum = INT2NUM(sig); 687 rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe); 688 } 689 TH_POP_TAG(); 690 cur_th = GET_THREAD(); 691 cur_th->interrupt_mask = old_interrupt_mask; 692 693 if (state) { 694 /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */ 695 JUMP_TAG(state); 696 } 697} 698 699void 700rb_trap_exit(void) 701{ 702 rb_vm_t *vm = GET_VM(); 703 VALUE trap_exit = vm->trap_list[0].cmd; 704 705 if (trap_exit) { 706 vm->trap_list[0].cmd = 0; 707 signal_exec(trap_exit, vm->trap_list[0].safe, 0); 708 } 709} 710 711void 712rb_signal_exec(rb_thread_t *th, int sig) 713{ 714 rb_vm_t *vm = GET_VM(); 715 VALUE cmd = vm->trap_list[sig].cmd; 716 int safe = vm->trap_list[sig].safe; 717 718 if (cmd == 0) { 719 switch (sig) { 720 case SIGINT: 721 rb_interrupt(); 722 break; 723#ifdef SIGHUP 724 case SIGHUP: 725#endif 726#ifdef SIGQUIT 727 case SIGQUIT: 728#endif 729#ifdef SIGTERM 730 case SIGTERM: 731#endif 732#ifdef SIGALRM 733 case SIGALRM: 734#endif 735#ifdef SIGUSR1 736 case SIGUSR1: 737#endif 738#ifdef SIGUSR2 739 case SIGUSR2: 740#endif 741 rb_threadptr_signal_raise(th, sig); 742 break; 743 } 744 } 745 else if (cmd == Qundef) { 746 rb_threadptr_signal_exit(th); 747 } 748 else { 749 signal_exec(cmd, safe, sig); 750 } 751} 752 753static sighandler_t 754default_handler(int sig) 755{ 756 sighandler_t func; 757 switch (sig) { 758 case SIGINT: 759#ifdef SIGHUP 760 case SIGHUP: 761#endif 762#ifdef SIGQUIT 763 case SIGQUIT: 764#endif 765#ifdef SIGTERM 766 case SIGTERM: 767#endif 768#ifdef SIGALRM 769 case SIGALRM: 770#endif 771#ifdef SIGUSR1 772 case SIGUSR1: 773#endif 774#ifdef SIGUSR2 775 case SIGUSR2: 776#endif 777 func = sighandler; 778 break; 779#ifdef SIGBUS 780 case SIGBUS: 781 func = (sighandler_t)sigbus; 782 break; 783#endif 784#ifdef SIGSEGV 785 case SIGSEGV: 786 func = (sighandler_t)sigsegv; 787 break; 788#endif 789#ifdef SIGPIPE 790 case SIGPIPE: 791 func = SIG_IGN; 792 break; 793#endif 794 default: 795 func = SIG_DFL; 796 break; 797 } 798 799 return func; 800} 801 802static sighandler_t 803trap_handler(VALUE *cmd, int sig) 804{ 805 sighandler_t func = sighandler; 806 VALUE command; 807 808 if (NIL_P(*cmd)) { 809 func = SIG_IGN; 810 } 811 else { 812 command = rb_check_string_type(*cmd); 813 if (NIL_P(command) && SYMBOL_P(*cmd)) { 814 command = rb_id2str(SYM2ID(*cmd)); 815 if (!command) rb_raise(rb_eArgError, "bad handler"); 816 } 817 if (!NIL_P(command)) { 818 SafeStringValue(command); /* taint check */ 819 *cmd = command; 820 switch (RSTRING_LEN(command)) { 821 case 0: 822 goto sig_ign; 823 break; 824 case 14: 825 if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) { 826 func = SIG_DFL; 827 *cmd = 0; 828 } 829 break; 830 case 7: 831 if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) { 832sig_ign: 833 func = SIG_IGN; 834 *cmd = 0; 835 } 836 else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) { 837sig_dfl: 838 func = default_handler(sig); 839 *cmd = 0; 840 } 841 else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) { 842 goto sig_dfl; 843 } 844 break; 845 case 6: 846 if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) { 847 goto sig_ign; 848 } 849 break; 850 case 4: 851 if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) { 852 *cmd = Qundef; 853 } 854 break; 855 } 856 } 857 else { 858 rb_proc_t *proc; 859 GetProcPtr(*cmd, proc); 860 (void)proc; 861 } 862 } 863 864 return func; 865} 866 867static int 868trap_signm(VALUE vsig) 869{ 870 int sig = -1; 871 const char *s; 872 873 switch (TYPE(vsig)) { 874 case T_FIXNUM: 875 sig = FIX2INT(vsig); 876 if (sig < 0 || sig >= NSIG) { 877 rb_raise(rb_eArgError, "invalid signal number (%d)", sig); 878 } 879 break; 880 881 case T_SYMBOL: 882 s = rb_id2name(SYM2ID(vsig)); 883 if (!s) rb_raise(rb_eArgError, "bad signal"); 884 goto str_signal; 885 886 default: 887 s = StringValuePtr(vsig); 888 889 str_signal: 890 if (strncmp("SIG", s, 3) == 0) 891 s += 3; 892 sig = signm2signo(s); 893 if (sig == 0 && strcmp(s, "EXIT") != 0) 894 rb_raise(rb_eArgError, "unsupported signal SIG%s", s); 895 } 896 return sig; 897} 898 899static VALUE 900trap(int sig, sighandler_t func, VALUE command) 901{ 902 sighandler_t oldfunc; 903 VALUE oldcmd; 904 rb_vm_t *vm = GET_VM(); 905 906 /* 907 * Be careful. ruby_signal() and trap_list[sig].cmd must be changed 908 * atomically. In current implementation, we only need to don't call 909 * RUBY_VM_CHECK_INTS(). 910 */ 911 oldfunc = ruby_signal(sig, func); 912 oldcmd = vm->trap_list[sig].cmd; 913 switch (oldcmd) { 914 case 0: 915 if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE"); 916 else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT"); 917 else oldcmd = Qnil; 918 break; 919 case Qundef: 920 oldcmd = rb_str_new2("EXIT"); 921 break; 922 } 923 924 vm->trap_list[sig].cmd = command; 925 vm->trap_list[sig].safe = rb_safe_level(); 926 927 return oldcmd; 928} 929 930static int 931reserved_signal_p(int signo) 932{ 933/* Synchronous signal can't deliver to main thread */ 934#ifdef SIGSEGV 935 if (signo == SIGSEGV) 936 return 1; 937#endif 938#ifdef SIGBUS 939 if (signo == SIGBUS) 940 return 1; 941#endif 942#ifdef SIGILL 943 if (signo == SIGILL) 944 return 1; 945#endif 946#ifdef SIGFPE 947 if (signo == SIGFPE) 948 return 1; 949#endif 950 951/* used ubf internal see thread_pthread.c. */ 952#ifdef SIGVTALRM 953 if (signo == SIGVTALRM) 954 return 1; 955#endif 956 957 return 0; 958} 959 960/* 961 * call-seq: 962 * Signal.trap( signal, command ) -> obj 963 * Signal.trap( signal ) {| | block } -> obj 964 * 965 * Specifies the handling of signals. The first parameter is a signal 966 * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a 967 * signal number. The characters ``SIG'' may be omitted from the 968 * signal name. The command or block specifies code to be run when the 969 * signal is raised. 970 * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal 971 * will be ignored. 972 * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler 973 * will be invoked. 974 * If the command is ``EXIT'', the script will be terminated by the signal. 975 * If the command is ``SYSTEM_DEFAULT'', the operating system's default 976 * handler will be invoked. 977 * Otherwise, the given command or block will be run. 978 * The special signal name ``EXIT'' or signal number zero will be 979 * invoked just prior to program termination. 980 * trap returns the previous handler for the given signal. 981 * 982 * Signal.trap(0, proc { puts "Terminating: #{$$}" }) 983 * Signal.trap("CLD") { puts "Child died" } 984 * fork && Process.wait 985 * 986 * produces: 987 * Terminating: 27461 988 * Child died 989 * Terminating: 27460 990 */ 991static VALUE 992sig_trap(int argc, VALUE *argv) 993{ 994 int sig; 995 sighandler_t func; 996 VALUE cmd; 997 998 rb_secure(2); 999 rb_check_arity(argc, 1, 2); 1000 1001 sig = trap_signm(argv[0]); 1002 if (reserved_signal_p(sig)) { 1003 const char *name = signo2signm(sig); 1004 if (name) 1005 rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name); 1006 else 1007 rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig); 1008 } 1009 1010 if (argc == 1) { 1011 cmd = rb_block_proc(); 1012 func = sighandler; 1013 } 1014 else { 1015 cmd = argv[1]; 1016 func = trap_handler(&cmd, sig); 1017 } 1018 1019 if (OBJ_TAINTED(cmd)) { 1020 rb_raise(rb_eSecurityError, "Insecure: tainted signal trap"); 1021 } 1022 1023 return trap(sig, func, cmd); 1024} 1025 1026/* 1027 * call-seq: 1028 * Signal.list -> a_hash 1029 * 1030 * Returns a list of signal names mapped to the corresponding 1031 * underlying signal numbers. 1032 * 1033 * Signal.list #=> {"EXIT"=>0, "HUP"=>1, "INT"=>2, "QUIT"=>3, "ILL"=>4, "TRAP"=>5, "IOT"=>6, "ABRT"=>6, "FPE"=>8, "KILL"=>9, "BUS"=>7, "SEGV"=>11, "SYS"=>31, "PIPE"=>13, "ALRM"=>14, "TERM"=>15, "URG"=>23, "STOP"=>19, "TSTP"=>20, "CONT"=>18, "CHLD"=>17, "CLD"=>17, "TTIN"=>21, "TTOU"=>22, "IO"=>29, "XCPU"=>24, "XFSZ"=>25, "VTALRM"=>26, "PROF"=>27, "WINCH"=>28, "USR1"=>10, "USR2"=>12, "PWR"=>30, "POLL"=>29} 1034 */ 1035static VALUE 1036sig_list(void) 1037{ 1038 VALUE h = rb_hash_new(); 1039 const struct signals *sigs; 1040 1041 for (sigs = siglist; sigs->signm; sigs++) { 1042 rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo)); 1043 } 1044 return h; 1045} 1046 1047static void 1048install_sighandler(int signum, sighandler_t handler) 1049{ 1050 sighandler_t old; 1051 1052 /* At this time, there is no subthread. Then sigmask guarantee atomics. */ 1053 rb_disable_interrupt(); 1054 old = ruby_signal(signum, handler); 1055 /* signal handler should be inherited during exec. */ 1056 if (old != SIG_DFL) { 1057 ruby_signal(signum, old); 1058 } 1059 rb_enable_interrupt(); 1060} 1061 1062#if defined(SIGCLD) || defined(SIGCHLD) 1063static void 1064init_sigchld(int sig) 1065{ 1066 sighandler_t oldfunc; 1067 1068 rb_disable_interrupt(); 1069 oldfunc = ruby_signal(sig, SIG_DFL); 1070 if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) { 1071 ruby_signal(sig, oldfunc); 1072 } else { 1073 GET_VM()->trap_list[sig].cmd = 0; 1074 } 1075 rb_enable_interrupt(); 1076} 1077#endif 1078 1079void 1080ruby_sig_finalize(void) 1081{ 1082 sighandler_t oldfunc; 1083 1084 oldfunc = ruby_signal(SIGINT, SIG_IGN); 1085 if (oldfunc == sighandler) { 1086 ruby_signal(SIGINT, SIG_DFL); 1087 } 1088} 1089 1090 1091int ruby_enable_coredump = 0; 1092#ifndef RUBY_DEBUG_ENV 1093#define ruby_enable_coredump 0 1094#endif 1095 1096/* 1097 * Many operating systems allow signals to be sent to running 1098 * processes. Some signals have a defined effect on the process, while 1099 * others may be trapped at the code level and acted upon. For 1100 * example, your process may trap the USR1 signal and use it to toggle 1101 * debugging, and may use TERM to initiate a controlled shutdown. 1102 * 1103 * pid = fork do 1104 * Signal.trap("USR1") do 1105 * $debug = !$debug 1106 * puts "Debug now: #$debug" 1107 * end 1108 * Signal.trap("TERM") do 1109 * puts "Terminating..." 1110 * shutdown() 1111 * end 1112 * # . . . do some work . . . 1113 * end 1114 * 1115 * Process.detach(pid) 1116 * 1117 * # Controlling program: 1118 * Process.kill("USR1", pid) 1119 * # ... 1120 * Process.kill("USR1", pid) 1121 * # ... 1122 * Process.kill("TERM", pid) 1123 * 1124 * produces: 1125 * Debug now: true 1126 * Debug now: false 1127 * Terminating... 1128 * 1129 * The list of available signal names and their interpretation is 1130 * system dependent. Signal delivery semantics may also vary between 1131 * systems; in particular signal delivery may not always be reliable. 1132 */ 1133void 1134Init_signal(void) 1135{ 1136 VALUE mSignal = rb_define_module("Signal"); 1137 1138 rb_define_global_function("trap", sig_trap, -1); 1139 rb_define_module_function(mSignal, "trap", sig_trap, -1); 1140 rb_define_module_function(mSignal, "list", sig_list, 0); 1141 rb_define_module_function(mSignal, "signame", sig_signame, 1); 1142 1143 rb_define_method(rb_eSignal, "initialize", esignal_init, -1); 1144 rb_define_method(rb_eSignal, "signo", esignal_signo, 0); 1145 rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message")); 1146 rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1); 1147 1148 install_sighandler(SIGINT, sighandler); 1149#ifdef SIGHUP 1150 install_sighandler(SIGHUP, sighandler); 1151#endif 1152#ifdef SIGQUIT 1153 install_sighandler(SIGQUIT, sighandler); 1154#endif 1155#ifdef SIGTERM 1156 install_sighandler(SIGTERM, sighandler); 1157#endif 1158#ifdef SIGALRM 1159 install_sighandler(SIGALRM, sighandler); 1160#endif 1161#ifdef SIGUSR1 1162 install_sighandler(SIGUSR1, sighandler); 1163#endif 1164#ifdef SIGUSR2 1165 install_sighandler(SIGUSR2, sighandler); 1166#endif 1167 1168 if (!ruby_enable_coredump) { 1169#ifdef SIGBUS 1170 install_sighandler(SIGBUS, (sighandler_t)sigbus); 1171#endif 1172#ifdef SIGSEGV 1173# ifdef USE_SIGALTSTACK 1174 rb_register_sigaltstack(GET_THREAD()); 1175# endif 1176 install_sighandler(SIGSEGV, (sighandler_t)sigsegv); 1177#endif 1178 } 1179#ifdef SIGPIPE 1180 install_sighandler(SIGPIPE, SIG_IGN); 1181#endif 1182 1183#if defined(SIGCLD) 1184 init_sigchld(SIGCLD); 1185#elif defined(SIGCHLD) 1186 init_sigchld(SIGCHLD); 1187#endif 1188} 1189