From: nobu.nokada@... Date: 2002-03-26T00:56:32+09:00 Subject: Re: Restoring old signal handlers Hi, At Mon, 25 Mar 2002 23:37:34 +0900, Paul Brannan wrote: > If I do this twice, then when SIGCHLD is received: > > handler2 -> calls handler1 -> calls original handler > > How can I remove handler1 in such a way that when SIGCHLD is recieved: > > handler2 -> calls original handler You may need a signal handler manager? module Signal @handlers = [] def self.chain_handler(sig) catch (:cancel) do @handlers[sig].reverse_each do |handler| if String === handler eval(handler) else handler.call(sig) end end end end def self.signum(sig) Integer === sig or sig = list[sig.to_s.sub(/^SIG/, "")] sig end def self.install(sig, handler = proc) sig = signum(sig) if handler (@handlers[sig] ||= []) << handler trap(sig, method(:chain_handler).to_proc) end handler end def self.uninstall(sig, handler) sig = signum(sig) if handlers = @handlers[sig] handlers.delete(handler) clear_handler(sig) if handlers.empty? end handler end def self.clear(sig = nil) if sig sig = signum(sig) @handlers[sig] = nil trap(sig, nil) else @handlers.each_with_index do |handler, sig| trap(sig, nil) if handler end @handlers.clear end nil end end if $0 == __FILE__ handler1 = Signal.install("CLD") do puts "handler 1" end handler2 = Signal.install("CLD") do puts "handler 2" throw :cancel end handler3 = Signal.install("CLD") do puts "handler 3" end Process.waitpid fork {} # => handler 3 & 2 Signal.uninstall("CLD", handler2) Process.waitpid fork {} # => handler 3 & 1 end -- Nobu Nakada