module Signal
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.
Public Class Methods
Source
static VALUE
sig_list(VALUE _)
{
VALUE h = rb_hash_new();
const struct signals *sigs;
FOREACH_SIGNAL(sigs, 0) {
rb_hash_aset(h, rb_fstring_cstr(sigs->signm), INT2FIX(sigs->signo));
}
return h;
}
Returns a list of signal names mapped to the corresponding underlying signal numbers.
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}
Source
static VALUE
sig_signame(VALUE recv, VALUE signo)
{
const char *signame = signo2signm(NUM2INT(signo));
if (!signame) return Qnil;
return rb_str_new_cstr(signame);
}
Convert signal number to signal name. Returns nil if the signo is an invalid signal number.
Signal.trap("INT") { |signo| puts Signal.signame(signo) } Process.kill("INT", 0)
produces:
INT
Source
static VALUE
sig_trap(int argc, VALUE *argv, VALUE _)
{
int sig;
sighandler_t func;
VALUE cmd;
rb_check_arity(argc, 1, 2);
sig = trap_signm(argv[0]);
if (reserved_signal_p(sig)) {
const char *name = signo2signm(sig);
if (name)
rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
else
rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
}
if (argc == 1) {
cmd = rb_block_proc();
func = sighandler;
}
else {
cmd = argv[1];
func = trap_handler(&cmd, sig);
}
if (rb_obj_is_proc(cmd) &&
!rb_ractor_main_p() && !rb_ractor_shareable_p(cmd)) {
cmd = rb_proc_isolate(cmd);
}
return trap(sig, func, cmd);
}
Specifies the handling of signals. Returns the previous handler for the given signal.
Argument signal is a signal name (a string or symbol such as SIGALRM or SIGUSR1) or an integer signal number. When signal is a string or symbol, the leading characters SIG may be omitted.
Argument command or block provided specifies code to be run when the signal is raised.
Argument command may also be a string or symbol with the following special values:
-
IGNORE,SIG_IGN: the signal will be ignored. -
DEFAULT,SIG_DFL: Ruby’s default handler will be invoked. -
EXIT: the process will be terminated by the signal. -
SYSTEM_DEFAULT: the operating system’s default handler will be invoked.
The special signal name EXIT or signal number zero will be invoked just prior to program termination:
Signal.trap(0, proc { puts "Terminating: #{$$}" }) Signal.trap("CLD") { puts "Child died" } fork && Process.wait
Outputs:
Terminating: 27461 Child died Terminating: 27460