|
Ruby
2.0.0p594(2014-10-27revision48167)
|
00001 /********************************************************************** 00002 00003 signal.c - 00004 00005 $Author: usa $ 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 if (old.sa_flags & SA_SIGINFO) 00525 return (sighandler_t)old.sa_sigaction; 00526 else 00527 return old.sa_handler; 00528 } 00529 00530 sighandler_t 00531 posix_signal(int signum, sighandler_t handler) 00532 { 00533 return ruby_signal(signum, handler); 00534 } 00535 00536 #else /* !POSIX_SIGNAL */ 00537 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler))) 00538 #if 0 /* def HAVE_NATIVETHREAD */ 00539 static sighandler_t 00540 ruby_nativethread_signal(int signum, sighandler_t handler) 00541 { 00542 sighandler_t old; 00543 00544 old = signal(signum, handler); 00545 rb_trap_accept_nativethreads[signum] = 1; 00546 return old; 00547 } 00548 #endif 00549 #endif 00550 00551 static RETSIGTYPE 00552 sighandler(int sig) 00553 { 00554 ATOMIC_INC(signal_buff.cnt[sig]); 00555 ATOMIC_INC(signal_buff.size); 00556 rb_thread_wakeup_timer_thread(); 00557 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) 00558 ruby_signal(sig, sighandler); 00559 #endif 00560 } 00561 00562 int 00563 rb_signal_buff_size(void) 00564 { 00565 return signal_buff.size; 00566 } 00567 00568 #if HAVE_PTHREAD_H 00569 #include <pthread.h> 00570 #endif 00571 00572 static void 00573 rb_disable_interrupt(void) 00574 { 00575 #ifdef HAVE_PTHREAD_SIGMASK 00576 sigset_t mask; 00577 sigfillset(&mask); 00578 pthread_sigmask(SIG_SETMASK, &mask, NULL); 00579 #endif 00580 } 00581 00582 static void 00583 rb_enable_interrupt(void) 00584 { 00585 #ifdef HAVE_PTHREAD_SIGMASK 00586 sigset_t mask; 00587 sigemptyset(&mask); 00588 pthread_sigmask(SIG_SETMASK, &mask, NULL); 00589 #endif 00590 } 00591 00592 int 00593 rb_get_next_signal(void) 00594 { 00595 int i, sig = 0; 00596 00597 if (signal_buff.size != 0) { 00598 for (i=1; i<RUBY_NSIG; i++) { 00599 if (signal_buff.cnt[i] > 0) { 00600 ATOMIC_DEC(signal_buff.cnt[i]); 00601 ATOMIC_DEC(signal_buff.size); 00602 sig = i; 00603 break; 00604 } 00605 } 00606 } 00607 return sig; 00608 } 00609 00610 00611 #if defined(USE_SIGALTSTACK) || defined(_WIN32) 00612 static void 00613 check_stack_overflow(const void *addr) 00614 { 00615 int ruby_stack_overflowed_p(const rb_thread_t *, const void *); 00616 NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); 00617 rb_thread_t *th = ruby_current_thread; 00618 if (ruby_stack_overflowed_p(th, addr)) { 00619 ruby_thread_stack_overflow(th); 00620 } 00621 } 00622 #ifdef _WIN32 00623 #define CHECK_STACK_OVERFLOW() check_stack_overflow(0) 00624 #else 00625 #define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr) 00626 #endif 00627 #else 00628 #define CHECK_STACK_OVERFLOW() (void)0 00629 #endif 00630 00631 #ifdef SIGBUS 00632 static RETSIGTYPE 00633 sigbus(int sig SIGINFO_ARG) 00634 { 00635 /* 00636 * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page. 00637 * and it's delivered as SIGBUS instaed of SIGSEGV to userland. It's crazy 00638 * wrong IMHO. but anyway we have to care it. Sigh. 00639 */ 00640 #if defined __APPLE__ 00641 CHECK_STACK_OVERFLOW(); 00642 #endif 00643 rb_bug("Bus Error"); 00644 } 00645 #endif 00646 00647 #ifdef SIGSEGV 00648 static void ruby_abort(void) 00649 { 00650 #ifdef __sun 00651 /* Solaris's abort() is async signal unsafe. Of course, it is not 00652 * POSIX compliant. 00653 */ 00654 raise(SIGABRT); 00655 #else 00656 abort(); 00657 #endif 00658 00659 } 00660 00661 static int segv_received = 0; 00662 extern int ruby_disable_gc_stress; 00663 00664 static RETSIGTYPE 00665 sigsegv(int sig SIGINFO_ARG) 00666 { 00667 if (segv_received) { 00668 ssize_t RB_UNUSED_VAR(err); 00669 char msg[] = "SEGV received in SEGV handler\n"; 00670 00671 err = write(2, msg, sizeof(msg)); 00672 ruby_abort(); 00673 } 00674 00675 CHECK_STACK_OVERFLOW(); 00676 00677 segv_received = 1; 00678 ruby_disable_gc_stress = 1; 00679 rb_bug("Segmentation fault"); 00680 } 00681 #endif 00682 00683 static void 00684 signal_exec(VALUE cmd, int safe, int sig) 00685 { 00686 rb_thread_t *cur_th = GET_THREAD(); 00687 volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask; 00688 int state; 00689 00690 /* 00691 * workaround the following race: 00692 * 1. signal_enque queues signal for execution 00693 * 2. user calls trap(sig, "IGNORE"), setting SIG_IGN 00694 * 3. rb_signal_exec runs on queued signal 00695 */ 00696 if (IMMEDIATE_P(cmd)) 00697 return; 00698 00699 cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK; 00700 TH_PUSH_TAG(cur_th); 00701 if ((state = EXEC_TAG()) == 0) { 00702 VALUE signum = INT2NUM(sig); 00703 rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe); 00704 } 00705 TH_POP_TAG(); 00706 cur_th = GET_THREAD(); 00707 cur_th->interrupt_mask = old_interrupt_mask; 00708 00709 if (state) { 00710 /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */ 00711 JUMP_TAG(state); 00712 } 00713 } 00714 00715 void 00716 rb_trap_exit(void) 00717 { 00718 rb_vm_t *vm = GET_VM(); 00719 VALUE trap_exit = vm->trap_list[0].cmd; 00720 00721 if (trap_exit) { 00722 vm->trap_list[0].cmd = 0; 00723 signal_exec(trap_exit, vm->trap_list[0].safe, 0); 00724 } 00725 } 00726 00727 void 00728 rb_signal_exec(rb_thread_t *th, int sig) 00729 { 00730 rb_vm_t *vm = GET_VM(); 00731 VALUE cmd = vm->trap_list[sig].cmd; 00732 int safe = vm->trap_list[sig].safe; 00733 00734 if (cmd == 0) { 00735 switch (sig) { 00736 case SIGINT: 00737 rb_interrupt(); 00738 break; 00739 #ifdef SIGHUP 00740 case SIGHUP: 00741 #endif 00742 #ifdef SIGQUIT 00743 case SIGQUIT: 00744 #endif 00745 #ifdef SIGTERM 00746 case SIGTERM: 00747 #endif 00748 #ifdef SIGALRM 00749 case SIGALRM: 00750 #endif 00751 #ifdef SIGUSR1 00752 case SIGUSR1: 00753 #endif 00754 #ifdef SIGUSR2 00755 case SIGUSR2: 00756 #endif 00757 rb_threadptr_signal_raise(th, sig); 00758 break; 00759 } 00760 } 00761 else if (cmd == Qundef) { 00762 rb_threadptr_signal_exit(th); 00763 } 00764 else { 00765 signal_exec(cmd, safe, sig); 00766 } 00767 } 00768 00769 static sighandler_t 00770 default_handler(int sig) 00771 { 00772 sighandler_t func; 00773 switch (sig) { 00774 case SIGINT: 00775 #ifdef SIGHUP 00776 case SIGHUP: 00777 #endif 00778 #ifdef SIGQUIT 00779 case SIGQUIT: 00780 #endif 00781 #ifdef SIGTERM 00782 case SIGTERM: 00783 #endif 00784 #ifdef SIGALRM 00785 case SIGALRM: 00786 #endif 00787 #ifdef SIGUSR1 00788 case SIGUSR1: 00789 #endif 00790 #ifdef SIGUSR2 00791 case SIGUSR2: 00792 #endif 00793 func = sighandler; 00794 break; 00795 #ifdef SIGBUS 00796 case SIGBUS: 00797 func = (sighandler_t)sigbus; 00798 break; 00799 #endif 00800 #ifdef SIGSEGV 00801 case SIGSEGV: 00802 func = (sighandler_t)sigsegv; 00803 break; 00804 #endif 00805 #ifdef SIGPIPE 00806 case SIGPIPE: 00807 func = SIG_IGN; 00808 break; 00809 #endif 00810 default: 00811 func = SIG_DFL; 00812 break; 00813 } 00814 00815 return func; 00816 } 00817 00818 static sighandler_t 00819 trap_handler(VALUE *cmd, int sig) 00820 { 00821 sighandler_t func = sighandler; 00822 VALUE command; 00823 00824 if (NIL_P(*cmd)) { 00825 func = SIG_IGN; 00826 } 00827 else { 00828 command = rb_check_string_type(*cmd); 00829 if (NIL_P(command) && SYMBOL_P(*cmd)) { 00830 command = rb_id2str(SYM2ID(*cmd)); 00831 if (!command) rb_raise(rb_eArgError, "bad handler"); 00832 } 00833 if (!NIL_P(command)) { 00834 SafeStringValue(command); /* taint check */ 00835 *cmd = command; 00836 switch (RSTRING_LEN(command)) { 00837 case 0: 00838 goto sig_ign; 00839 break; 00840 case 14: 00841 if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) { 00842 func = SIG_DFL; 00843 *cmd = 0; 00844 } 00845 break; 00846 case 7: 00847 if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) { 00848 sig_ign: 00849 func = SIG_IGN; 00850 *cmd = Qtrue; 00851 } 00852 else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) { 00853 sig_dfl: 00854 func = default_handler(sig); 00855 *cmd = 0; 00856 } 00857 else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) { 00858 goto sig_dfl; 00859 } 00860 break; 00861 case 6: 00862 if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) { 00863 goto sig_ign; 00864 } 00865 break; 00866 case 4: 00867 if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) { 00868 *cmd = Qundef; 00869 } 00870 break; 00871 } 00872 } 00873 else { 00874 rb_proc_t *proc; 00875 GetProcPtr(*cmd, proc); 00876 (void)proc; 00877 } 00878 } 00879 00880 return func; 00881 } 00882 00883 static int 00884 trap_signm(VALUE vsig) 00885 { 00886 int sig = -1; 00887 const char *s; 00888 00889 switch (TYPE(vsig)) { 00890 case T_FIXNUM: 00891 sig = FIX2INT(vsig); 00892 if (sig < 0 || sig >= NSIG) { 00893 rb_raise(rb_eArgError, "invalid signal number (%d)", sig); 00894 } 00895 break; 00896 00897 case T_SYMBOL: 00898 s = rb_id2name(SYM2ID(vsig)); 00899 if (!s) rb_raise(rb_eArgError, "bad signal"); 00900 goto str_signal; 00901 00902 default: 00903 s = StringValuePtr(vsig); 00904 00905 str_signal: 00906 if (strncmp("SIG", s, 3) == 0) 00907 s += 3; 00908 sig = signm2signo(s); 00909 if (sig == 0 && strcmp(s, "EXIT") != 0) 00910 rb_raise(rb_eArgError, "unsupported signal SIG%s", s); 00911 } 00912 return sig; 00913 } 00914 00915 static VALUE 00916 trap(int sig, sighandler_t func, VALUE command) 00917 { 00918 sighandler_t oldfunc; 00919 VALUE oldcmd; 00920 rb_vm_t *vm = GET_VM(); 00921 00922 /* 00923 * Be careful. ruby_signal() and trap_list[sig].cmd must be changed 00924 * atomically. In current implementation, we only need to don't call 00925 * RUBY_VM_CHECK_INTS(). 00926 */ 00927 oldfunc = ruby_signal(sig, func); 00928 oldcmd = vm->trap_list[sig].cmd; 00929 switch (oldcmd) { 00930 case 0: 00931 case Qtrue: 00932 if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE"); 00933 else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT"); 00934 else oldcmd = Qnil; 00935 break; 00936 case Qnil: 00937 break; 00938 case Qundef: 00939 oldcmd = rb_str_new2("EXIT"); 00940 break; 00941 } 00942 00943 vm->trap_list[sig].cmd = command; 00944 vm->trap_list[sig].safe = rb_safe_level(); 00945 00946 return oldcmd; 00947 } 00948 00949 static int 00950 reserved_signal_p(int signo) 00951 { 00952 /* Synchronous signal can't deliver to main thread */ 00953 #ifdef SIGSEGV 00954 if (signo == SIGSEGV) 00955 return 1; 00956 #endif 00957 #ifdef SIGBUS 00958 if (signo == SIGBUS) 00959 return 1; 00960 #endif 00961 #ifdef SIGILL 00962 if (signo == SIGILL) 00963 return 1; 00964 #endif 00965 #ifdef SIGFPE 00966 if (signo == SIGFPE) 00967 return 1; 00968 #endif 00969 00970 /* used ubf internal see thread_pthread.c. */ 00971 #ifdef SIGVTALRM 00972 if (signo == SIGVTALRM) 00973 return 1; 00974 #endif 00975 00976 return 0; 00977 } 00978 00979 /* 00980 * call-seq: 00981 * Signal.trap( signal, command ) -> obj 00982 * Signal.trap( signal ) {| | block } -> obj 00983 * 00984 * Specifies the handling of signals. The first parameter is a signal 00985 * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a 00986 * signal number. The characters ``SIG'' may be omitted from the 00987 * signal name. The command or block specifies code to be run when the 00988 * signal is raised. 00989 * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal 00990 * will be ignored. 00991 * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler 00992 * will be invoked. 00993 * If the command is ``EXIT'', the script will be terminated by the signal. 00994 * If the command is ``SYSTEM_DEFAULT'', the operating system's default 00995 * handler will be invoked. 00996 * Otherwise, the given command or block will be run. 00997 * The special signal name ``EXIT'' or signal number zero will be 00998 * invoked just prior to program termination. 00999 * trap returns the previous handler for the given signal. 01000 * 01001 * Signal.trap(0, proc { puts "Terminating: #{$$}" }) 01002 * Signal.trap("CLD") { puts "Child died" } 01003 * fork && Process.wait 01004 * 01005 * produces: 01006 * Terminating: 27461 01007 * Child died 01008 * Terminating: 27460 01009 */ 01010 static VALUE 01011 sig_trap(int argc, VALUE *argv) 01012 { 01013 int sig; 01014 sighandler_t func; 01015 VALUE cmd; 01016 01017 rb_secure(2); 01018 rb_check_arity(argc, 1, 2); 01019 01020 sig = trap_signm(argv[0]); 01021 if (reserved_signal_p(sig)) { 01022 const char *name = signo2signm(sig); 01023 if (name) 01024 rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name); 01025 else 01026 rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig); 01027 } 01028 01029 if (argc == 1) { 01030 cmd = rb_block_proc(); 01031 func = sighandler; 01032 } 01033 else { 01034 cmd = argv[1]; 01035 func = trap_handler(&cmd, sig); 01036 } 01037 01038 if (OBJ_TAINTED(cmd)) { 01039 rb_raise(rb_eSecurityError, "Insecure: tainted signal trap"); 01040 } 01041 01042 return trap(sig, func, cmd); 01043 } 01044 01045 /* 01046 * call-seq: 01047 * Signal.list -> a_hash 01048 * 01049 * Returns a list of signal names mapped to the corresponding 01050 * underlying signal numbers. 01051 * 01052 * 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} 01053 */ 01054 static VALUE 01055 sig_list(void) 01056 { 01057 VALUE h = rb_hash_new(); 01058 const struct signals *sigs; 01059 01060 for (sigs = siglist; sigs->signm; sigs++) { 01061 rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo)); 01062 } 01063 return h; 01064 } 01065 01066 static void 01067 install_sighandler(int signum, sighandler_t handler) 01068 { 01069 sighandler_t old; 01070 01071 /* At this time, there is no subthread. Then sigmask guarantee atomics. */ 01072 rb_disable_interrupt(); 01073 old = ruby_signal(signum, handler); 01074 /* signal handler should be inherited during exec. */ 01075 if (old != SIG_DFL) { 01076 ruby_signal(signum, old); 01077 } 01078 rb_enable_interrupt(); 01079 } 01080 01081 #if defined(SIGCLD) || defined(SIGCHLD) 01082 static void 01083 init_sigchld(int sig) 01084 { 01085 sighandler_t oldfunc; 01086 01087 rb_disable_interrupt(); 01088 oldfunc = ruby_signal(sig, SIG_DFL); 01089 if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) { 01090 ruby_signal(sig, oldfunc); 01091 } else { 01092 GET_VM()->trap_list[sig].cmd = 0; 01093 } 01094 rb_enable_interrupt(); 01095 } 01096 #endif 01097 01098 void 01099 ruby_sig_finalize(void) 01100 { 01101 sighandler_t oldfunc; 01102 01103 oldfunc = ruby_signal(SIGINT, SIG_IGN); 01104 if (oldfunc == sighandler) { 01105 ruby_signal(SIGINT, SIG_DFL); 01106 } 01107 } 01108 01109 01110 int ruby_enable_coredump = 0; 01111 #ifndef RUBY_DEBUG_ENV 01112 #define ruby_enable_coredump 0 01113 #endif 01114 01115 /* 01116 * Many operating systems allow signals to be sent to running 01117 * processes. Some signals have a defined effect on the process, while 01118 * others may be trapped at the code level and acted upon. For 01119 * example, your process may trap the USR1 signal and use it to toggle 01120 * debugging, and may use TERM to initiate a controlled shutdown. 01121 * 01122 * pid = fork do 01123 * Signal.trap("USR1") do 01124 * $debug = !$debug 01125 * puts "Debug now: #$debug" 01126 * end 01127 * Signal.trap("TERM") do 01128 * puts "Terminating..." 01129 * shutdown() 01130 * end 01131 * # . . . do some work . . . 01132 * end 01133 * 01134 * Process.detach(pid) 01135 * 01136 * # Controlling program: 01137 * Process.kill("USR1", pid) 01138 * # ... 01139 * Process.kill("USR1", pid) 01140 * # ... 01141 * Process.kill("TERM", pid) 01142 * 01143 * produces: 01144 * Debug now: true 01145 * Debug now: false 01146 * Terminating... 01147 * 01148 * The list of available signal names and their interpretation is 01149 * system dependent. Signal delivery semantics may also vary between 01150 * systems; in particular signal delivery may not always be reliable. 01151 */ 01152 void 01153 Init_signal(void) 01154 { 01155 VALUE mSignal = rb_define_module("Signal"); 01156 01157 rb_define_global_function("trap", sig_trap, -1); 01158 rb_define_module_function(mSignal, "trap", sig_trap, -1); 01159 rb_define_module_function(mSignal, "list", sig_list, 0); 01160 rb_define_module_function(mSignal, "signame", sig_signame, 1); 01161 01162 rb_define_method(rb_eSignal, "initialize", esignal_init, -1); 01163 rb_define_method(rb_eSignal, "signo", esignal_signo, 0); 01164 rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message")); 01165 rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1); 01166 01167 install_sighandler(SIGINT, sighandler); 01168 #ifdef SIGHUP 01169 install_sighandler(SIGHUP, sighandler); 01170 #endif 01171 #ifdef SIGQUIT 01172 install_sighandler(SIGQUIT, sighandler); 01173 #endif 01174 #ifdef SIGTERM 01175 install_sighandler(SIGTERM, sighandler); 01176 #endif 01177 #ifdef SIGALRM 01178 install_sighandler(SIGALRM, sighandler); 01179 #endif 01180 #ifdef SIGUSR1 01181 install_sighandler(SIGUSR1, sighandler); 01182 #endif 01183 #ifdef SIGUSR2 01184 install_sighandler(SIGUSR2, sighandler); 01185 #endif 01186 01187 if (!ruby_enable_coredump) { 01188 #ifdef SIGBUS 01189 install_sighandler(SIGBUS, (sighandler_t)sigbus); 01190 #endif 01191 #ifdef SIGSEGV 01192 # ifdef USE_SIGALTSTACK 01193 rb_register_sigaltstack(GET_THREAD()); 01194 # endif 01195 install_sighandler(SIGSEGV, (sighandler_t)sigsegv); 01196 #endif 01197 } 01198 #ifdef SIGPIPE 01199 install_sighandler(SIGPIPE, SIG_IGN); 01200 #endif 01201 01202 #if defined(SIGCLD) 01203 init_sigchld(SIGCLD); 01204 #elif defined(SIGCHLD) 01205 init_sigchld(SIGCHLD); 01206 #endif 01207 } 01208
1.7.6.1