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 end Process.detach(pid) 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.
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.listSource
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:
INTSource
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. The first parameter is a signal name (a string such as âSIGALRMâ, âSIGUSR1â, and so on) or a signal number. The characters âSIGâ may be omitted from the signal name. The command or block specifies code to be run when the signal is raised. If the command is the string âIGNOREâ or âSIG_IGNâ, the signal will be ignored. If the command is âDEFAULTâ or âSIG_DFLâ, the Rubyâs default handler will be invoked. If the command is âEXITâ, the script will be terminated by the signal. If the command is âSYSTEM_DEFAULTâ, the operating systemâs default handler will be invoked. Otherwise, the given command or block will be run. The special signal name âEXITâ or signal number zero will be invoked just prior to program termination. trap returns the previous handler for the given signal.
Signal.trap(0, proc { puts "Terminating: #{$$}" }) Signal.trap("CLD") { puts "Child died" } fork && Process.wait
produces:
Terminating: 27461 Child died Terminating: 27460
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4