Change soft-fail to use the config, rather than env
[rbx.git] / kernel / core / signal.rb
blob2a84487e6a68ff829d78aec917cf8ba2364990df
1 # depends on: module.rb
3 module Signal
4   Names = {"EXIT" => 0}
6   @threads = {}
7   @handlers = {}
8   
9   def self.trap(sig, prc=nil, pass_ctx=false, &block)
10     sig = sig.to_s if sig.kind_of?(Symbol)
12     if sig.kind_of?(String)
13       osig = sig
15       if sig.prefix? "SIG"
16         sig = sig[3..-1]
17       end
19       if sig == "EXIT"
20         at_exit { block.call }
21         return
22       end
24       unless number = Names[sig]
25         raise ArgumentError, "Unknown signal '#{osig}'"
26       end
27     else
28       number = sig.to_i
29     end
31     if prc and block
32       raise ArgumentError, "Either a Proc or a block, not both."
33     elsif block
34       prc = block
35     end
37     old = @handlers[number]
39     @handlers[number] = prc
41     # If there is already at thread for this sig, give up.
42     return old if @threads[number]
44     chan = Channel.new
46     thr = Thread.new do
47       while true
48         ctx = chan.receive
50         # Run the handler in a new thread so chan.receive doesn't
51         # block signals during handler execution, e.g., a SIGINT
52         # during a sleep() in a SIGINT handler.
54         Thread.new do
55           if pass_ctx
56             obj = ctx
57           else
58             obj = number
59           end
61           begin
62             @handlers[number].call(obj)
63           rescue Object => e
64             Thread.main.raise e
65           end
66         end
67       end
68     end
70     @threads[number] = thr
72     Scheduler.send_on_signal chan, number
73     return old
74   end
75   
76   def self.action(sig, prc=nil, &block)
77     trap(sig, prc, true, &block)
78   end
80   def self.list
81     Names.dup
82   end
84   def self.after_loaded
85     Rubinius::RUBY_CONFIG.keys.each do |key|
86       if key[0, 20] == 'rbx.platform.signal.'
87         Names[ key[23, 100] ] = Rubinius::RUBY_CONFIG[key]
88       end
89     end
90     # special case of signal.c
91     if Names["CHLD"]
92       Names["CLD"] = Names["CHLD"]
93     end
94   end
96 end