1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Copyright 2011 Alexis Laferrière <alexis.laf@xymus.net>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Module to manage standard C signals
22 #define _POSIX_SOURCE 1
27 Structure to manage each possible signals
28 are used in an array of 32 maximum signals.
29 This array is global to the software.
31 struct nit_signals_ent {
32 char raised; /* !=0 if has been raised */
33 SignalHandler handler; /* instance to receive call */
34 char safely; /* if !=0 then manage signal safely, otherwise react when raised */
35 } nit_signals_list[32] = {0x0};
37 /* Receiver to all signals
38 If unsafe, it calls directly the Nit receiver,
39 otherwise it marks the signal as raised and returns.
41 void receiver(int sig)
43 if (sig < 32 && sig >=0)
45 if (nit_signals_list[sig].safely) {
46 nit_signals_list[sig].raised += 1;
48 SignalHandler_receive_signal(nit_signals_list[sig].handler, sig);
54 # Receives the callback from system when a given signal arise
55 interface SignalHandler
56 # Called on any signal received
57 fun receive_signal
(signal
: Int) `{
60 # Called on any unsafe signal received
61 fun receive_signal_unsafe
(signal
: Int) `{
64 # Set the receiver as the handler of the signal
65 # If safely, receiver will be called when check_signals in invoked
66 # otherwise the receiver is invoked when the signal is raised, it may
67 # crash the Nit system but is unavoidable for unstoppable signals
68 fun handle_signal
(signal
: Int, safely
: Bool) import
70 SignalHandler last_handler;
71 if (signal < 32 && signal >=0) {
73 sigemptyset(&act.sa_mask);
75 act.sa_handler = receiver;
77 sigaction(signal, &act, NULL);
79 last_handler = nit_signals_list[signal].handler;
80 if (last_handler != NULL)
81 SignalHandler_decr_ref(last_handler);
83 nit_signals_list[signal].handler = recv;
84 SignalHandler_incr_ref(recv);
86 nit_signals_list[signal].safely = safely;
90 # Set to ignore the signal
91 fun ignore_signal
(signal
: Int) `{
92 SignalHandler last_handler;
93 if (signal < 32 && signal >=0) {
95 sigemptyset(&act.sa_mask);
97 act.sa_handler = SIG_IGN;
98 sigaction(signal, &act, NULL);
100 last_handler = nit_signals_list[signal].handler;
101 if (last_handler != NULL)
102 SignalHandler_decr_ref(last_handler);
106 # Set default action for the signal
107 fun default_signal
(signal
: Int) `{
108 SignalHandler last_handler;
109 if (signal < 32 && signal >=0) {
110 struct sigaction act;
111 sigemptyset(&act.sa_mask);
113 act.sa_handler = SIG_DFL;
114 sigaction(signal, &act, NULL);
116 last_handler = nit_signals_list[signal].handler;
117 if (last_handler != NULL)
118 SignalHandler_decr_ref(last_handler);
122 fun sigalarm
: Int do return 14
123 fun sighup
: Int do return 1
124 fun sigint
: Int do return 2
125 fun sigkill
: Int do return 9
126 fun sigpipe
: Int do return 13
127 fun sigterm
: Int do return 15
128 fun sigabrt
: Int do return 6
129 fun sigfpe
: Int do return 8
130 fun sigquit
: Int do return 3
131 fun sigsegv
: Int do return 11
134 redef interface Object
136 # Check signals for safe operation
137 # will callback receiver of raised signals
138 # can callback any instance of SignalHandler, not just this one
139 protected fun check_signals
: Bool is extern import SignalHandler::receive_signal
`{
141 int raised_something = 0;
143 for (sig = 0; sig < 32; sig ++)
144 if (nit_signals_list[sig].raised) {
145 nit_signals_list[sig].raised = 0;
146 raised_something = 1;
147 SignalHandler_receive_signal(nit_signals_list[sig].handler, sig);
150 return raised_something;
154 # can callback any instance of SignalHandler, not just this one
155 protected fun set_alarm
(sec
: Int) `{ alarm(sec); `}