Temporary tag for this failure. Updated CI spec coming.
[rbx.git] / kernel / core / signal.rb
blob55ab1365514506e7a561526a6c4cfccc82f0eb6f
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     if sig.kind_of?(String)
11       osig = sig
13       if sig.prefix? "SIG"
14         sig = sig[3..-1]
15       end
17       unless number = Names[sig]
18         raise ArgumentError, "Unknown signal '#{osig}'"
19       end
20     else
21       number = sig.to_i
22     end
24     if prc and block
25       raise ArgumentError, "Either a Proc or a block, not both."
26     elsif block
27       prc = block
28     end
30     old = @handlers[number]
32     @handlers[number] = prc
34     # If there is already at thread for this sig, give up.
35     return old if @threads[number]
37     chan = Channel.new
39     thr = Thread.new do
40       while true
41         ctx = chan.receive
43         if pass_ctx
44           obj = ctx
45         else
46           obj = number
47         end
49         begin
50           @handlers[number].call(obj)
51         rescue Object => e
52           if $DEBUG
53             STDERR.pus "Exception while running signal handler: #{e.message}"
54           end
55         end
56       end
57     end
59     @threads[number] = thr
61     Scheduler.send_on_signal chan, number
62     return old
63   end
64   
65   def self.action(sig, prc=nil, &block)
66     trap(sig, prc, true, &block)
67   end
69   def self.list
70     Names.dup
71   end
73   def self.after_loaded
74     Rubinius::RUBY_CONFIG.keys.each do |key|
75       if key[0, 20] == 'rbx.platform.signal.'
76         Names[ key[23, 100] ] = Rubinius::RUBY_CONFIG[key]
77       end
78     end
79     # special case of signal.c
80     if Names["CHLD"]
81       Names["CLD"] = Names["CHLD"]
82     end
83   end
85 end