static void install_sighandler(int signum, sighandler_t handler) { sighandler_t old; rb_disable_interrupt(); old = ruby_signal(signum, handler); if (old != SIG_DFL) { ruby_signal(signum, old); } rb_enable_interrupt(); }
static void init_sigchld(int sig) { sighandler_t oldfunc; rb_disable_interrupt(); oldfunc = ruby_signal(sig, SIG_DFL); if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) { ruby_signal(sig, oldfunc); } else { GET_VM()->trap_list[sig].cmd = 0; } rb_enable_interrupt(); }
static void install_sighandler(int signum, sighandler_t handler) { sighandler_t old; /* At this time, there is no subthread. Then sigmask guarantee atomics. */ rb_disable_interrupt(); old = ruby_signal(signum, handler); /* signal handler should be inherited during exec. */ if (old != SIG_DFL) { ruby_signal(signum, old); } rb_enable_interrupt(); }
int rb_get_next_signal(void) { int i, sig = 0; for (i=1; i<RUBY_NSIG; i++) { if (signal_buff.cnt[i] > 0) { rb_disable_interrupt(); { ATOMIC_DEC(signal_buff.cnt[i]); ATOMIC_DEC(signal_buff.size); } rb_enable_interrupt(); sig = i; break; } } return sig; }
int rb_get_next_signal(rb_vm_t *vm) { int i, sig = 0; for (i=1; i<RUBY_NSIG; i++) { if (vm->signal_buff[i] > 0) { rb_disable_interrupt(); { ATOMIC_DEC(vm->signal_buff[i]); ATOMIC_DEC(vm->buffered_signal_size); } rb_enable_interrupt(); sig = i; break; } } return sig; }
/* * Many operating systems allow signals to be sent to running * processes. Some signals have a defined effect on the process, while * others may be trapped at the code level and acted upon. For * example, your process may trap the USR1 signal and use it to toggle * debugging, and may use TERM to initiate a controlled shutdown. * * pid = fork do * Signal.trap("USR1") do * $debug = !$debug * puts "Debug now: #$debug" * end * Signal.trap("TERM") do * puts "Terminating..." * shutdown() * end * # . . . do some work . . . * end * * Process.detach(pid) * * # Controlling program: * Process.kill("USR1", pid) * # ... * Process.kill("USR1", pid) * # ... * Process.kill("TERM", pid) * * produces: * Debug now: true * Debug now: false * Terminating... * * The list of available signal names and their interpretation is * system dependent. Signal delivery semantics may also vary between * systems; in particular signal delivery may not always be reliable. */ void Init_signal(void) { VALUE mSignal = rb_define_module("Signal"); rb_define_global_function("trap", sig_trap, -1); rb_define_module_function(mSignal, "trap", sig_trap, -1); rb_define_module_function(mSignal, "list", sig_list, 0); rb_define_module_function(mSignal, "signame", sig_signame, 1); rb_define_method(rb_eSignal, "initialize", esignal_init, -1); rb_define_method(rb_eSignal, "signo", esignal_signo, 0); rb_alias(rb_eSignal, rb_intern_const("signm"), rb_intern_const("message")); rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1); /* At this time, there is no subthread. Then sigmask guarantee atomics. */ rb_disable_interrupt(); install_sighandler(SIGINT, sighandler); #ifdef SIGHUP install_sighandler(SIGHUP, sighandler); #endif #ifdef SIGQUIT install_sighandler(SIGQUIT, sighandler); #endif #ifdef SIGTERM install_sighandler(SIGTERM, sighandler); #endif #ifdef SIGALRM install_sighandler(SIGALRM, sighandler); #endif #ifdef SIGUSR1 install_sighandler(SIGUSR1, sighandler); #endif #ifdef SIGUSR2 install_sighandler(SIGUSR2, sighandler); #endif if (!ruby_enable_coredump) { #ifdef SIGBUS install_sighandler(SIGBUS, (sighandler_t)sigbus); #endif #ifdef SIGILL install_sighandler(SIGILL, (sighandler_t)sigill); #endif #ifdef SIGSEGV # ifdef USE_SIGALTSTACK rb_register_sigaltstack(GET_THREAD()); # endif install_sighandler(SIGSEGV, (sighandler_t)sigsegv); #endif } #ifdef SIGPIPE install_sighandler(SIGPIPE, SIG_IGN); #endif #if defined(SIGCLD) init_sigchld(SIGCLD); #elif defined(SIGCHLD) init_sigchld(SIGCHLD); #endif rb_enable_interrupt(); }