Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /********************************************************************** 00002 00003 signal.c - 00004 00005 $Author: nagachika $ 00006 created at: Tue Dec 20 10:13:44 JST 1994 00007 00008 Copyright (C) 1993-2007 Yukihiro Matsumoto 00009 Copyright (C) 2000 Network Applied Communication Laboratory, Inc. 00010 Copyright (C) 2000 Information-technology Promotion Agency, Japan 00011 00012 **********************************************************************/ 00013 00014 #include "ruby/ruby.h" 00015 #include "vm_core.h" 00016 #include <signal.h> 00017 #include <stdio.h> 00018 #include <errno.h> 00019 #include "ruby_atomic.h" 00020 #include "eval_intern.h" 00021 00022 #if defined(__native_client__) && defined(NACL_NEWLIB) 00023 # include "nacl/signal.h" 00024 #endif 00025 00026 #ifdef NEED_RUBY_ATOMIC_OPS 00027 rb_atomic_t 00028 ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val) 00029 { 00030 rb_atomic_t old = *ptr; 00031 *ptr = val; 00032 return old; 00033 } 00034 00035 rb_atomic_t 00036 ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp, 00037 rb_atomic_t newval) 00038 { 00039 rb_atomic_t old = *ptr; 00040 if (old == cmp) { 00041 *ptr = newval; 00042 } 00043 return old; 00044 } 00045 #endif 00046 00047 #if defined(__BEOS__) || defined(__HAIKU__) 00048 #undef SIGBUS 00049 #endif 00050 00051 #ifndef NSIG 00052 # define NSIG (_SIGMAX + 1) /* For QNX */ 00053 #endif 00054 00055 static const struct signals { 00056 const char *signm; 00057 int signo; 00058 } siglist [] = { 00059 {"EXIT", 0}, 00060 #ifdef SIGHUP 00061 {"HUP", SIGHUP}, 00062 #endif 00063 {"INT", SIGINT}, 00064 #ifdef SIGQUIT 00065 {"QUIT", SIGQUIT}, 00066 #endif 00067 #ifdef SIGILL 00068 {"ILL", SIGILL}, 00069 #endif 00070 #ifdef SIGTRAP 00071 {"TRAP", SIGTRAP}, 00072 #endif 00073 #ifdef SIGIOT 00074 {"IOT", SIGIOT}, 00075 #endif 00076 #ifdef SIGABRT 00077 {"ABRT", SIGABRT}, 00078 #endif 00079 #ifdef SIGEMT 00080 {"EMT", SIGEMT}, 00081 #endif 00082 #ifdef SIGFPE 00083 {"FPE", SIGFPE}, 00084 #endif 00085 #ifdef SIGKILL 00086 {"KILL", SIGKILL}, 00087 #endif 00088 #ifdef SIGBUS 00089 {"BUS", SIGBUS}, 00090 #endif 00091 #ifdef SIGSEGV 00092 {"SEGV", SIGSEGV}, 00093 #endif 00094 #ifdef SIGSYS 00095 {"SYS", SIGSYS}, 00096 #endif 00097 #ifdef SIGPIPE 00098 {"PIPE", SIGPIPE}, 00099 #endif 00100 #ifdef SIGALRM 00101 {"ALRM", SIGALRM}, 00102 #endif 00103 #ifdef SIGTERM 00104 {"TERM", SIGTERM}, 00105 #endif 00106 #ifdef SIGURG 00107 {"URG", SIGURG}, 00108 #endif 00109 #ifdef SIGSTOP 00110 {"STOP", SIGSTOP}, 00111 #endif 00112 #ifdef SIGTSTP 00113 {"TSTP", SIGTSTP}, 00114 #endif 00115 #ifdef SIGCONT 00116 {"CONT", SIGCONT}, 00117 #endif 00118 #ifdef SIGCHLD 00119 {"CHLD", SIGCHLD}, 00120 #endif 00121 #ifdef SIGCLD 00122 {"CLD", SIGCLD}, 00123 #else 00124 # ifdef SIGCHLD 00125 {"CLD", SIGCHLD}, 00126 # endif 00127 #endif 00128 #ifdef SIGTTIN 00129 {"TTIN", SIGTTIN}, 00130 #endif 00131 #ifdef SIGTTOU 00132 {"TTOU", SIGTTOU}, 00133 #endif 00134 #ifdef SIGIO 00135 {"IO", SIGIO}, 00136 #endif 00137 #ifdef SIGXCPU 00138 {"XCPU", SIGXCPU}, 00139 #endif 00140 #ifdef SIGXFSZ 00141 {"XFSZ", SIGXFSZ}, 00142 #endif 00143 #ifdef SIGVTALRM 00144 {"VTALRM", SIGVTALRM}, 00145 #endif 00146 #ifdef SIGPROF 00147 {"PROF", SIGPROF}, 00148 #endif 00149 #ifdef SIGWINCH 00150 {"WINCH", SIGWINCH}, 00151 #endif 00152 #ifdef SIGUSR1 00153 {"USR1", SIGUSR1}, 00154 #endif 00155 #ifdef SIGUSR2 00156 {"USR2", SIGUSR2}, 00157 #endif 00158 #ifdef SIGLOST 00159 {"LOST", SIGLOST}, 00160 #endif 00161 #ifdef SIGMSG 00162 {"MSG", SIGMSG}, 00163 #endif 00164 #ifdef SIGPWR 00165 {"PWR", SIGPWR}, 00166 #endif 00167 #ifdef SIGPOLL 00168 {"POLL", SIGPOLL}, 00169 #endif 00170 #ifdef SIGDANGER 00171 {"DANGER", SIGDANGER}, 00172 #endif 00173 #ifdef SIGMIGRATE 00174 {"MIGRATE", SIGMIGRATE}, 00175 #endif 00176 #ifdef SIGPRE 00177 {"PRE", SIGPRE}, 00178 #endif 00179 #ifdef SIGGRANT 00180 {"GRANT", SIGGRANT}, 00181 #endif 00182 #ifdef SIGRETRACT 00183 {"RETRACT", SIGRETRACT}, 00184 #endif 00185 #ifdef SIGSOUND 00186 {"SOUND", SIGSOUND}, 00187 #endif 00188 #ifdef SIGINFO 00189 {"INFO", SIGINFO}, 00190 #endif 00191 {NULL, 0} 00192 }; 00193 00194 static int 00195 signm2signo(const char *nm) 00196 { 00197 const struct signals *sigs; 00198 00199 for (sigs = siglist; sigs->signm; sigs++) 00200 if (strcmp(sigs->signm, nm) == 0) 00201 return sigs->signo; 00202 return 0; 00203 } 00204 00205 static const char* 00206 signo2signm(int no) 00207 { 00208 const struct signals *sigs; 00209 00210 for (sigs = siglist; sigs->signm; sigs++) 00211 if (sigs->signo == no) 00212 return sigs->signm; 00213 return 0; 00214 } 00215 00216 /* 00217 * call-seq: 00218 * Signal.signame(signo) -> string 00219 * 00220 * convert signal number to signal name 00221 * 00222 * Signal.trap("INT") { |signo| puts Signal.signame(signo) } 00223 * Process.kill("INT", 0) 00224 * 00225 * <em>produces:</em> 00226 * 00227 * INT 00228 */ 00229 static VALUE 00230 sig_signame(VALUE recv, VALUE signo) 00231 { 00232 const char *signame = signo2signm(NUM2INT(signo)); 00233 return rb_str_new_cstr(signame); 00234 } 00235 00236 const char * 00237 ruby_signal_name(int no) 00238 { 00239 return signo2signm(no); 00240 } 00241 00242 /* 00243 * call-seq: 00244 * SignalException.new(sig_name) -> signal_exception 00245 * SignalException.new(sig_number [, name]) -> signal_exception 00246 * 00247 * Construct a new SignalException object. +sig_name+ should be a known 00248 * signal name. 00249 */ 00250 00251 static VALUE 00252 esignal_init(int argc, VALUE *argv, VALUE self) 00253 { 00254 int argnum = 1; 00255 VALUE sig = Qnil; 00256 int signo; 00257 const char *signm; 00258 00259 if (argc > 0) { 00260 sig = rb_check_to_integer(argv[0], "to_int"); 00261 if (!NIL_P(sig)) argnum = 2; 00262 else sig = argv[0]; 00263 } 00264 rb_check_arity(argc, 1, argnum); 00265 if (argnum == 2) { 00266 signo = NUM2INT(sig); 00267 if (signo < 0 || signo > NSIG) { 00268 rb_raise(rb_eArgError, "invalid signal number (%d)", signo); 00269 } 00270 if (argc > 1) { 00271 sig = argv[1]; 00272 } 00273 else { 00274 signm = signo2signm(signo); 00275 if (signm) { 00276 sig = rb_sprintf("SIG%s", signm); 00277 } 00278 else { 00279 sig = rb_sprintf("SIG%u", signo); 00280 } 00281 } 00282 } 00283 else { 00284 signm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig); 00285 if (strncmp(signm, "SIG", 3) == 0) signm += 3; 00286 signo = signm2signo(signm); 00287 if (!signo) { 00288 rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm); 00289 } 00290 sig = rb_sprintf("SIG%s", signm); 00291 } 00292 rb_call_super(1, &sig); 00293 rb_iv_set(self, "signo", INT2NUM(signo)); 00294 00295 return self; 00296 } 00297 00298 /* 00299 * call-seq: 00300 * signal_exception.signo -> num 00301 * 00302 * Returns a signal number. 00303 */ 00304 00305 static VALUE 00306 esignal_signo(VALUE self) 00307 { 00308 return rb_iv_get(self, "signo"); 00309 } 00310 00311 /* :nodoc: */ 00312 static VALUE 00313 interrupt_init(int argc, VALUE *argv, VALUE self) 00314 { 00315 VALUE args[2]; 00316 00317 args[0] = INT2FIX(SIGINT); 00318 rb_scan_args(argc, argv, "01", &args[1]); 00319 return rb_call_super(2, args); 00320 } 00321 00322 void 00323 ruby_default_signal(int sig) 00324 { 00325 signal(sig, SIG_DFL); 00326 raise(sig); 00327 } 00328 00329 /* 00330 * call-seq: 00331 * Process.kill(signal, pid, ...) -> fixnum 00332 * 00333 * Sends the given signal to the specified process id(s) if _pid_ is positive. 00334 * If _pid_ is zero _signal_ is sent to all processes whose group ID is equal 00335 * to the group ID of the process. _signal_ may be an integer signal number or 00336 * a POSIX signal name (either with or without a +SIG+ prefix). If _signal_ is 00337 * negative (or starts with a minus sign), kills process groups instead of 00338 * processes. Not all signals are available on all platforms. 00339 * 00340 * pid = fork do 00341 * Signal.trap("HUP") { puts "Ouch!"; exit } 00342 * # ... do some work ... 00343 * end 00344 * # ... 00345 * Process.kill("HUP", pid) 00346 * Process.wait 00347 * 00348 * <em>produces:</em> 00349 * 00350 * Ouch! 00351 * 00352 * If _signal_ is an integer but wrong for signal, 00353 * <code>Errno::EINVAL</code> or +RangeError+ will be raised. 00354 * Otherwise unless _signal_ is a +String+ or a +Symbol+, and a known 00355 * signal name, +ArgumentError+ will be raised. 00356 * 00357 * Also, <code>Errno::ESRCH</code> or +RangeError+ for invalid _pid_, 00358 * <code>Errno::EPERM</code> when failed because of no privilege, 00359 * will be raised. In these cases, signals may have been sent to 00360 * preceding processes. 00361 */ 00362 00363 VALUE 00364 rb_f_kill(int argc, VALUE *argv) 00365 { 00366 #ifndef HAVE_KILLPG 00367 #define killpg(pg, sig) kill(-(pg), (sig)) 00368 #endif 00369 int negative = 0; 00370 int sig; 00371 int i; 00372 volatile VALUE str; 00373 const char *s; 00374 00375 rb_secure(2); 00376 rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS); 00377 00378 switch (TYPE(argv[0])) { 00379 case T_FIXNUM: 00380 sig = FIX2INT(argv[0]); 00381 break; 00382 00383 case T_SYMBOL: 00384 s = rb_id2name(SYM2ID(argv[0])); 00385 if (!s) rb_raise(rb_eArgError, "bad signal"); 00386 goto str_signal; 00387 00388 case T_STRING: 00389 s = RSTRING_PTR(argv[0]); 00390 str_signal: 00391 if (s[0] == '-') { 00392 negative++; 00393 s++; 00394 } 00395 if (strncmp("SIG", s, 3) == 0) 00396 s += 3; 00397 if ((sig = signm2signo(s)) == 0) 00398 rb_raise(rb_eArgError, "unsupported name `SIG%s'", s); 00399 00400 if (negative) 00401 sig = -sig; 00402 break; 00403 00404 default: 00405 str = rb_check_string_type(argv[0]); 00406 if (!NIL_P(str)) { 00407 s = RSTRING_PTR(str); 00408 goto str_signal; 00409 } 00410 rb_raise(rb_eArgError, "bad signal type %s", 00411 rb_obj_classname(argv[0])); 00412 break; 00413 } 00414 00415 if (sig < 0) { 00416 sig = -sig; 00417 for (i=1; i<argc; i++) { 00418 if (killpg(NUM2PIDT(argv[i]), sig) < 0) 00419 rb_sys_fail(0); 00420 } 00421 } 00422 else { 00423 for (i=1; i<argc; i++) { 00424 if (kill(NUM2PIDT(argv[i]), sig) < 0) 00425 rb_sys_fail(0); 00426 } 00427 } 00428 return INT2FIX(i-1); 00429 } 00430 00431 static struct { 00432 rb_atomic_t cnt[RUBY_NSIG]; 00433 rb_atomic_t size; 00434 } signal_buff; 00435 00436 #ifdef __dietlibc__ 00437 #define sighandler_t sh_t 00438 #endif 00439 00440 typedef RETSIGTYPE (*sighandler_t)(int); 00441 #ifdef USE_SIGALTSTACK 00442 typedef void ruby_sigaction_t(int, siginfo_t*, void*); 00443 #define SIGINFO_ARG , siginfo_t *info, void *ctx 00444 #else 00445 typedef RETSIGTYPE ruby_sigaction_t(int); 00446 #define SIGINFO_ARG 00447 #endif 00448 00449 #ifdef USE_SIGALTSTACK 00450 int rb_sigaltstack_size(void) 00451 { 00452 /* XXX: BSD_vfprintf() uses >1500KiB stack and x86-64 need >5KiB stack. */ 00453 int size = 8192; 00454 00455 #ifdef MINSIGSTKSZ 00456 if (size < MINSIGSTKSZ) 00457 size = MINSIGSTKSZ; 00458 #endif 00459 #if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) 00460 { 00461 int pagesize; 00462 pagesize = (int)sysconf(_SC_PAGE_SIZE); 00463 if (size < pagesize) 00464 size = pagesize; 00465 } 00466 #endif 00467 00468 return size; 00469 } 00470 00471 /* alternate stack for SIGSEGV */ 00472 void 00473 rb_register_sigaltstack(rb_thread_t *th) 00474 { 00475 stack_t newSS, oldSS; 00476 00477 if (!th->altstack) 00478 rb_bug("rb_register_sigaltstack: th->altstack not initialized\n"); 00479 00480 newSS.ss_sp = th->altstack; 00481 newSS.ss_size = rb_sigaltstack_size(); 00482 newSS.ss_flags = 0; 00483 00484 sigaltstack(&newSS, &oldSS); /* ignore error. */ 00485 } 00486 #endif /* USE_SIGALTSTACK */ 00487 00488 #ifdef POSIX_SIGNAL 00489 static sighandler_t 00490 ruby_signal(int signum, sighandler_t handler) 00491 { 00492 struct sigaction sigact, old; 00493 00494 #if 0 00495 rb_trap_accept_nativethreads[signum] = 0; 00496 #endif 00497 00498 sigemptyset(&sigact.sa_mask); 00499 #ifdef USE_SIGALTSTACK 00500 sigact.sa_sigaction = (ruby_sigaction_t*)handler; 00501 sigact.sa_flags = SA_SIGINFO; 00502 #else 00503 sigact.sa_handler = handler; 00504 sigact.sa_flags = 0; 00505 #endif 00506 00507 #ifdef SA_NOCLDWAIT 00508 if (signum == SIGCHLD && handler == SIG_IGN) 00509 sigact.sa_flags |= SA_NOCLDWAIT; 00510 #endif 00511 #if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK) 00512 if (signum == SIGSEGV 00513 #ifdef SIGBUS 00514 || signum == SIGBUS 00515 #endif 00516 ) 00517 sigact.sa_flags |= SA_ONSTACK; 00518 #endif 00519 if (sigaction(signum, &sigact, &old) < 0) { 00520 if (errno != 0 && errno != EINVAL) { 00521 rb_bug_errno("sigaction", errno); 00522 } 00523 } 00524 return old.sa_handler; 00525 } 00526 00527 sighandler_t 00528 posix_signal(int signum, sighandler_t handler) 00529 { 00530 return ruby_signal(signum, handler); 00531 } 00532 00533 #else /* !POSIX_SIGNAL */ 00534 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler))) 00535 #if 0 /* def HAVE_NATIVETHREAD */ 00536 static sighandler_t 00537 ruby_nativethread_signal(int signum, sighandler_t handler) 00538 { 00539 sighandler_t old; 00540 00541 old = signal(signum, handler); 00542 rb_trap_accept_nativethreads[signum] = 1; 00543 return old; 00544 } 00545 #endif 00546 #endif 00547 00548 static RETSIGTYPE 00549 sighandler(int sig) 00550 { 00551 ATOMIC_INC(signal_buff.cnt[sig]); 00552 ATOMIC_INC(signal_buff.size); 00553 rb_thread_wakeup_timer_thread(); 00554 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) 00555 ruby_signal(sig, sighandler); 00556 #endif 00557 } 00558 00559 int 00560 rb_signal_buff_size(void) 00561 { 00562 return signal_buff.size; 00563 } 00564 00565 #if HAVE_PTHREAD_H 00566 #include <pthread.h> 00567 #endif 00568 00569 static void 00570 rb_disable_interrupt(void) 00571 { 00572 #ifdef HAVE_PTHREAD_SIGMASK 00573 sigset_t mask; 00574 sigfillset(&mask); 00575 pthread_sigmask(SIG_SETMASK, &mask, NULL); 00576 #endif 00577 } 00578 00579 static void 00580 rb_enable_interrupt(void) 00581 { 00582 #ifdef HAVE_PTHREAD_SIGMASK 00583 sigset_t mask; 00584 sigemptyset(&mask); 00585 pthread_sigmask(SIG_SETMASK, &mask, NULL); 00586 #endif 00587 } 00588 00589 int 00590 rb_get_next_signal(void) 00591 { 00592 int i, sig = 0; 00593 00594 if (signal_buff.size != 0) { 00595 for (i=1; i<RUBY_NSIG; i++) { 00596 if (signal_buff.cnt[i] > 0) { 00597 ATOMIC_DEC(signal_buff.cnt[i]); 00598 ATOMIC_DEC(signal_buff.size); 00599 sig = i; 00600 break; 00601 } 00602 } 00603 } 00604 return sig; 00605 } 00606 00607 00608 #ifdef USE_SIGALTSTACK 00609 static void 00610 check_stack_overflow(const void *addr) 00611 { 00612 int ruby_stack_overflowed_p(const rb_thread_t *, const void *); 00613 NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); 00614 rb_thread_t *th = GET_THREAD(); 00615 if (ruby_stack_overflowed_p(th, addr)) { 00616 ruby_thread_stack_overflow(th); 00617 } 00618 } 00619 #define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr) 00620 #else 00621 #define CHECK_STACK_OVERFLOW() (void)0 00622 #endif 00623 00624 #ifdef SIGBUS 00625 static RETSIGTYPE 00626 sigbus(int sig SIGINFO_ARG) 00627 { 00628 /* 00629 * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page. 00630 * and it's delivered as SIGBUS instaed of SIGSEGV to userland. It's crazy 00631 * wrong IMHO. but anyway we have to care it. Sigh. 00632 */ 00633 #if defined __APPLE__ 00634 CHECK_STACK_OVERFLOW(); 00635 #endif 00636 rb_bug("Bus Error"); 00637 } 00638 #endif 00639 00640 #ifdef SIGSEGV 00641 static void ruby_abort(void) 00642 { 00643 #ifdef __sun 00644 /* Solaris's abort() is async signal unsafe. Of course, it is not 00645 * POSIX compliant. 00646 */ 00647 raise(SIGABRT); 00648 #else 00649 abort(); 00650 #endif 00651 00652 } 00653 00654 static int segv_received = 0; 00655 extern int ruby_disable_gc_stress; 00656 00657 static RETSIGTYPE 00658 sigsegv(int sig SIGINFO_ARG) 00659 { 00660 if (segv_received) { 00661 ssize_t RB_UNUSED_VAR(err); 00662 char msg[] = "SEGV received in SEGV handler\n"; 00663 00664 err = write(2, msg, sizeof(msg)); 00665 ruby_abort(); 00666 } 00667 00668 CHECK_STACK_OVERFLOW(); 00669 00670 segv_received = 1; 00671 ruby_disable_gc_stress = 1; 00672 rb_bug("Segmentation fault"); 00673 } 00674 #endif 00675 00676 static void 00677 signal_exec(VALUE cmd, int safe, int sig) 00678 { 00679 rb_thread_t *cur_th = GET_THREAD(); 00680 volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask; 00681 int state; 00682 00683 cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK; 00684 TH_PUSH_TAG(cur_th); 00685 if ((state = EXEC_TAG()) == 0) { 00686 VALUE signum = INT2NUM(sig); 00687 rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe); 00688 } 00689 TH_POP_TAG(); 00690 cur_th = GET_THREAD(); 00691 cur_th->interrupt_mask = old_interrupt_mask; 00692 00693 if (state) { 00694 /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */ 00695 JUMP_TAG(state); 00696 } 00697 } 00698 00699 void 00700 rb_trap_exit(void) 00701 { 00702 rb_vm_t *vm = GET_VM(); 00703 VALUE trap_exit = vm->trap_list[0].cmd; 00704 00705 if (trap_exit) { 00706 vm->trap_list[0].cmd = 0; 00707 signal_exec(trap_exit, vm->trap_list[0].safe, 0); 00708 } 00709 } 00710 00711 void 00712 rb_signal_exec(rb_thread_t *th, int sig) 00713 { 00714 rb_vm_t *vm = GET_VM(); 00715 VALUE cmd = vm->trap_list[sig].cmd; 00716 int safe = vm->trap_list[sig].safe; 00717 00718 if (cmd == 0) { 00719 switch (sig) { 00720 case SIGINT: 00721 rb_interrupt(); 00722 break; 00723 #ifdef SIGHUP 00724 case SIGHUP: 00725 #endif 00726 #ifdef SIGQUIT 00727 case SIGQUIT: 00728 #endif 00729 #ifdef SIGTERM 00730 case SIGTERM: 00731 #endif 00732 #ifdef SIGALRM 00733 case SIGALRM: 00734 #endif 00735 #ifdef SIGUSR1 00736 case SIGUSR1: 00737 #endif 00738 #ifdef SIGUSR2 00739 case SIGUSR2: 00740 #endif 00741 rb_threadptr_signal_raise(th, sig); 00742 break; 00743 } 00744 } 00745 else if (cmd == Qundef) { 00746 rb_threadptr_signal_exit(th); 00747 } 00748 else { 00749 signal_exec(cmd, safe, sig); 00750 } 00751 } 00752 00753 static sighandler_t 00754 default_handler(int sig) 00755 { 00756 sighandler_t func; 00757 switch (sig) { 00758 case SIGINT: 00759 #ifdef SIGHUP 00760 case SIGHUP: 00761 #endif 00762 #ifdef SIGQUIT 00763 case SIGQUIT: 00764 #endif 00765 #ifdef SIGTERM 00766 case SIGTERM: 00767 #endif 00768 #ifdef SIGALRM 00769 case SIGALRM: 00770 #endif 00771 #ifdef SIGUSR1 00772 case SIGUSR1: 00773 #endif 00774 #ifdef SIGUSR2 00775 case SIGUSR2: 00776 #endif 00777 func = sighandler; 00778 break; 00779 #ifdef SIGBUS 00780 case SIGBUS: 00781 func = (sighandler_t)sigbus; 00782 break; 00783 #endif 00784 #ifdef SIGSEGV 00785 case SIGSEGV: 00786 func = (sighandler_t)sigsegv; 00787 break; 00788 #endif 00789 #ifdef SIGPIPE 00790 case SIGPIPE: 00791 func = SIG_IGN; 00792 break; 00793 #endif 00794 default: 00795 func = SIG_DFL; 00796 break; 00797 } 00798 00799 return func; 00800 } 00801 00802 static sighandler_t 00803 trap_handler(VALUE *cmd, int sig) 00804 { 00805 sighandler_t func = sighandler; 00806 VALUE command; 00807 00808 if (NIL_P(*cmd)) { 00809 func = SIG_IGN; 00810 } 00811 else { 00812 command = rb_check_string_type(*cmd); 00813 if (NIL_P(command) && SYMBOL_P(*cmd)) { 00814 command = rb_id2str(SYM2ID(*cmd)); 00815 if (!command) rb_raise(rb_eArgError, "bad handler"); 00816 } 00817 if (!NIL_P(command)) { 00818 SafeStringValue(command); /* taint check */ 00819 *cmd = command; 00820 switch (RSTRING_LEN(command)) { 00821 case 0: 00822 goto sig_ign; 00823 break; 00824 case 14: 00825 if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) { 00826 func = SIG_DFL; 00827 *cmd = 0; 00828 } 00829 break; 00830 case 7: 00831 if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) { 00832 sig_ign: 00833 func = SIG_IGN; 00834 *cmd = 0; 00835 } 00836 else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) { 00837 sig_dfl: 00838 func = default_handler(sig); 00839 *cmd = 0; 00840 } 00841 else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) { 00842 goto sig_dfl; 00843 } 00844 break; 00845 case 6: 00846 if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) { 00847 goto sig_ign; 00848 } 00849 break; 00850 case 4: 00851 if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) { 00852 *cmd = Qundef; 00853 } 00854 break; 00855 } 00856 } 00857 else { 00858 rb_proc_t *proc; 00859 GetProcPtr(*cmd, proc); 00860 (void)proc; 00861 } 00862 } 00863 00864 return func; 00865 } 00866 00867 static int 00868 trap_signm(VALUE vsig) 00869 { 00870 int sig = -1; 00871 const char *s; 00872 00873 switch (TYPE(vsig)) { 00874 case T_FIXNUM: 00875 sig = FIX2INT(vsig); 00876 if (sig < 0 || sig >= NSIG) { 00877 rb_raise(rb_eArgError, "invalid signal number (%d)", sig); 00878 } 00879 break; 00880 00881 case T_SYMBOL: 00882 s = rb_id2name(SYM2ID(vsig)); 00883 if (!s) rb_raise(rb_eArgError, "bad signal"); 00884 goto str_signal; 00885 00886 default: 00887 s = StringValuePtr(vsig); 00888 00889 str_signal: 00890 if (strncmp("SIG", s, 3) == 0) 00891 s += 3; 00892 sig = signm2signo(s); 00893 if (sig == 0 && strcmp(s, "EXIT") != 0) 00894 rb_raise(rb_eArgError, "unsupported signal SIG%s", s); 00895 } 00896 return sig; 00897 } 00898 00899 static VALUE 00900 trap(int sig, sighandler_t func, VALUE command) 00901 { 00902 sighandler_t oldfunc; 00903 VALUE oldcmd; 00904 rb_vm_t *vm = GET_VM(); 00905 00906 /* 00907 * Be careful. ruby_signal() and trap_list[sig].cmd must be changed 00908 * atomically. In current implementation, we only need to don't call 00909 * RUBY_VM_CHECK_INTS(). 00910 */ 00911 oldfunc = ruby_signal(sig, func); 00912 oldcmd = vm->trap_list[sig].cmd; 00913 switch (oldcmd) { 00914 case 0: 00915 if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE"); 00916 else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT"); 00917 else oldcmd = Qnil; 00918 break; 00919 case Qundef: 00920 oldcmd = rb_str_new2("EXIT"); 00921 break; 00922 } 00923 00924 vm->trap_list[sig].cmd = command; 00925 vm->trap_list[sig].safe = rb_safe_level(); 00926 00927 return oldcmd; 00928 } 00929 00930 static int 00931 reserved_signal_p(int signo) 00932 { 00933 /* Synchronous signal can't deliver to main thread */ 00934 #ifdef SIGSEGV 00935 if (signo == SIGSEGV) 00936 return 1; 00937 #endif 00938 #ifdef SIGBUS 00939 if (signo == SIGBUS) 00940 return 1; 00941 #endif 00942 #ifdef SIGILL 00943 if (signo == SIGILL) 00944 return 1; 00945 #endif 00946 #ifdef SIGFPE 00947 if (signo == SIGFPE) 00948 return 1; 00949 #endif 00950 00951 /* used ubf internal see thread_pthread.c. */ 00952 #ifdef SIGVTALRM 00953 if (signo == SIGVTALRM) 00954 return 1; 00955 #endif 00956 00957 return 0; 00958 } 00959 00960 /* 00961 * call-seq: 00962 * Signal.trap( signal, command ) -> obj 00963 * Signal.trap( signal ) {| | block } -> obj 00964 * 00965 * Specifies the handling of signals. The first parameter is a signal 00966 * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a 00967 * signal number. The characters ``SIG'' may be omitted from the 00968 * signal name. The command or block specifies code to be run when the 00969 * signal is raised. 00970 * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal 00971 * will be ignored. 00972 * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler 00973 * will be invoked. 00974 * If the command is ``EXIT'', the script will be terminated by the signal. 00975 * If the command is ``SYSTEM_DEFAULT'', the operating system's default 00976 * handler will be invoked. 00977 * Otherwise, the given command or block will be run. 00978 * The special signal name ``EXIT'' or signal number zero will be 00979 * invoked just prior to program termination. 00980 * trap returns the previous handler for the given signal. 00981 * 00982 * Signal.trap(0, proc { puts "Terminating: #{$$}" }) 00983 * Signal.trap("CLD") { puts "Child died" } 00984 * fork && Process.wait 00985 * 00986 * produces: 00987 * Terminating: 27461 00988 * Child died 00989 * Terminating: 27460 00990 */ 00991 static VALUE 00992 sig_trap(int argc, VALUE *argv) 00993 { 00994 int sig; 00995 sighandler_t func; 00996 VALUE cmd; 00997 00998 rb_secure(2); 00999 rb_check_arity(argc, 1, 2); 01000 01001 sig = trap_signm(argv[0]); 01002 if (reserved_signal_p(sig)) { 01003 const char *name = signo2signm(sig); 01004 if (name) 01005 rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name); 01006 else 01007 rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig); 01008 } 01009 01010 if (argc == 1) { 01011 cmd = rb_block_proc(); 01012 func = sighandler; 01013 } 01014 else { 01015 cmd = argv[1]; 01016 func = trap_handler(&cmd, sig); 01017 } 01018 01019 if (OBJ_TAINTED(cmd)) { 01020 rb_raise(rb_eSecurityError, "Insecure: tainted signal trap"); 01021 } 01022 01023 return trap(sig, func, cmd); 01024 } 01025 01026 /* 01027 * call-seq: 01028 * Signal.list -> a_hash 01029 * 01030 * Returns a list of signal names mapped to the corresponding 01031 * underlying signal numbers. 01032 * 01033 * 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} 01034 */ 01035 static VALUE 01036 sig_list(void) 01037 { 01038 VALUE h = rb_hash_new(); 01039 const struct signals *sigs; 01040 01041 for (sigs = siglist; sigs->signm; sigs++) { 01042 rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo)); 01043 } 01044 return h; 01045 } 01046 01047 static void 01048 install_sighandler(int signum, sighandler_t handler) 01049 { 01050 sighandler_t old; 01051 01052 /* At this time, there is no subthread. Then sigmask guarantee atomics. */ 01053 rb_disable_interrupt(); 01054 old = ruby_signal(signum, handler); 01055 /* signal handler should be inherited during exec. */ 01056 if (old != SIG_DFL) { 01057 ruby_signal(signum, old); 01058 } 01059 rb_enable_interrupt(); 01060 } 01061 01062 #if defined(SIGCLD) || defined(SIGCHLD) 01063 static void 01064 init_sigchld(int sig) 01065 { 01066 sighandler_t oldfunc; 01067 01068 rb_disable_interrupt(); 01069 oldfunc = ruby_signal(sig, SIG_DFL); 01070 if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) { 01071 ruby_signal(sig, oldfunc); 01072 } else { 01073 GET_VM()->trap_list[sig].cmd = 0; 01074 } 01075 rb_enable_interrupt(); 01076 } 01077 #endif 01078 01079 void 01080 ruby_sig_finalize(void) 01081 { 01082 sighandler_t oldfunc; 01083 01084 oldfunc = ruby_signal(SIGINT, SIG_IGN); 01085 if (oldfunc == sighandler) { 01086 ruby_signal(SIGINT, SIG_DFL); 01087 } 01088 } 01089 01090 01091 int ruby_enable_coredump = 0; 01092 #ifndef RUBY_DEBUG_ENV 01093 #define ruby_enable_coredump 0 01094 #endif 01095 01096 /* 01097 * Many operating systems allow signals to be sent to running 01098 * processes. Some signals have a defined effect on the process, while 01099 * others may be trapped at the code level and acted upon. For 01100 * example, your process may trap the USR1 signal and use it to toggle 01101 * debugging, and may use TERM to initiate a controlled shutdown. 01102 * 01103 * pid = fork do 01104 * Signal.trap("USR1") do 01105 * $debug = !$debug 01106 * puts "Debug now: #$debug" 01107 * end 01108 * Signal.trap("TERM") do 01109 * puts "Terminating..." 01110 * shutdown() 01111 * end 01112 * # . . . do some work . . . 01113 * end 01114 * 01115 * Process.detach(pid) 01116 * 01117 * # Controlling program: 01118 * Process.kill("USR1", pid) 01119 * # ... 01120 * Process.kill("USR1", pid) 01121 * # ... 01122 * Process.kill("TERM", pid) 01123 * 01124 * produces: 01125 * Debug now: true 01126 * Debug now: false 01127 * Terminating... 01128 * 01129 * The list of available signal names and their interpretation is 01130 * system dependent. Signal delivery semantics may also vary between 01131 * systems; in particular signal delivery may not always be reliable. 01132 */ 01133 void 01134 Init_signal(void) 01135 { 01136 VALUE mSignal = rb_define_module("Signal"); 01137 01138 rb_define_global_function("trap", sig_trap, -1); 01139 rb_define_module_function(mSignal, "trap", sig_trap, -1); 01140 rb_define_module_function(mSignal, "list", sig_list, 0); 01141 rb_define_module_function(mSignal, "signame", sig_signame, 1); 01142 01143 rb_define_method(rb_eSignal, "initialize", esignal_init, -1); 01144 rb_define_method(rb_eSignal, "signo", esignal_signo, 0); 01145 rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message")); 01146 rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1); 01147 01148 install_sighandler(SIGINT, sighandler); 01149 #ifdef SIGHUP 01150 install_sighandler(SIGHUP, sighandler); 01151 #endif 01152 #ifdef SIGQUIT 01153 install_sighandler(SIGQUIT, sighandler); 01154 #endif 01155 #ifdef SIGTERM 01156 install_sighandler(SIGTERM, sighandler); 01157 #endif 01158 #ifdef SIGALRM 01159 install_sighandler(SIGALRM, sighandler); 01160 #endif 01161 #ifdef SIGUSR1 01162 install_sighandler(SIGUSR1, sighandler); 01163 #endif 01164 #ifdef SIGUSR2 01165 install_sighandler(SIGUSR2, sighandler); 01166 #endif 01167 01168 if (!ruby_enable_coredump) { 01169 #ifdef SIGBUS 01170 install_sighandler(SIGBUS, (sighandler_t)sigbus); 01171 #endif 01172 #ifdef SIGSEGV 01173 # ifdef USE_SIGALTSTACK 01174 rb_register_sigaltstack(GET_THREAD()); 01175 # endif 01176 install_sighandler(SIGSEGV, (sighandler_t)sigsegv); 01177 #endif 01178 } 01179 #ifdef SIGPIPE 01180 install_sighandler(SIGPIPE, SIG_IGN); 01181 #endif 01182 01183 #if defined(SIGCLD) 01184 init_sigchld(SIGCLD); 01185 #elif defined(SIGCHLD) 01186 init_sigchld(SIGCHLD); 01187 #endif 01188 } 01189