blob: a2ed72a986b772337d77eede9460983afab30aa1 [file] [log] [blame]
Guido van Rossum398d9fe1994-05-11 08:59:13 +00001/***********************************************************
2Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Signal module -- many thanks to Lance Ellinghouse */
26
27#include "allobjects.h"
28#include "modsupport.h"
29#include "ceval.h"
30#include "intrcheck.h"
31
32#include <signal.h>
33
34struct signalhandler_list {
35 int tripped;
36 object *func;
37};
38
39static struct signalhandler_list sig_list[NSIG];
40
41static object *default_sig_object;
42static object *default_ignore_object;
43static object *default_int_object;
44
45static object *
46default_int_handler(self, arg)
47 object *self;
48 object *arg;
49{
50 err_set(KeyboardInterrupt);
51 return NULL;
52}
53
54static RETSIGTYPE
55signal_handler(sig_num)
56 int sig_num;
57{
58 sig_list[sig_num].tripped = 1;
59 (void *)signal(sig_num, &signal_handler);
60}
61
62
63static object *
64signal_signal(self, args)
65 object *self; /* Not used */
66 object *args;
67{
68 object *obj;
69 int sig_num;
70 object *old_handler;
71 RETSIGTYPE (*func)();
72 if (!getargs(args, "(iO)", &sig_num, &obj))
73 return NULL;
74 if (sig_num < 1 || sig_num >= NSIG) {
75 err_setstr(ValueError, "signal number out of range");
76 return NULL;
77 }
78 if (obj == default_ignore_object)
79 func = SIG_IGN;
80 else if (obj == default_sig_object)
81 func = SIG_DFL;
82 else if (!is_methodobject(obj) &&
83 !is_funcobject(obj) &&
84 !is_instancemethodobject(obj)) {
85 err_setstr(TypeError,
86"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
87 return NULL;
88 }
89 else
90 func = signal_handler;
91 old_handler = sig_list[sig_num].func;
92 /* XXX is it always correct to clear tripped? */
93 sig_list[sig_num].tripped = 0;
94 INCREF(obj);
95 sig_list[sig_num].func = obj;
96 signal(sig_num, func);
97 return old_handler;
98}
99
100static object *
101signal_getsignal(self, args)
102 object *self; /* Not used */
103 object *args;
104{
105 int sig_num;
106 object *old_handler;
107 if (!getargs(args, "i", &sig_num))
108 return NULL;
109 if (sig_num < 1 || sig_num >= NSIG) {
110 err_setstr(ValueError, "signal number out of range");
111 return NULL;
112 }
113 old_handler = sig_list[sig_num].func;
114 INCREF(old_handler);
115 return old_handler;
116}
117
118
119/* List of functions defined in the module */
120
121static struct methodlist signal_methods[] = {
122 {"signal", signal_signal},
123 {"getsignal", signal_getsignal},
124 {NULL, NULL} /* sentinel */
125};
126
127void
128initsignal()
129{
130 object *m, *d, *x;
131 object *b_dict;
132 int i;
133 /* Create the module and add the functions */
134 m = initmodule("signal", signal_methods);
135
136 /* Add some symbolic constants to the module */
137 d = getmoduledict(m);
138
139 default_sig_object = newintobject((long)SIG_DFL);
140 dictinsert(d, "SIG_IGN", default_sig_object);
141 default_ignore_object = newintobject((long)SIG_IGN);
142 dictinsert(d, "SIG_DFL", default_ignore_object);
143 default_int_object = newmethodobject("default_int_handler",
144 default_int_handler,
145 (object *)NULL,
146 0);
147 dictinsert(d, "default_int_handler", default_int_object);
148
149 sig_list[0].tripped = 0;
150 for (i = 1; i < NSIG; i++) {
151 void *t; /* type cop-out */
152 t = signal(i, SIG_IGN);
153 signal(i, t);
154 sig_list[i].tripped = 0;
155 if (t == SIG_DFL)
156 sig_list[i].func = default_sig_object;
157 else if (t == SIG_IGN)
158 sig_list[i].func = default_ignore_object;
159 else
160 sig_list[i].func = None; /* None of our business */
161 INCREF(sig_list[i].func);
162 }
163 if (sig_list[SIGINT].func == default_sig_object) {
164 /* Install default int handler */
165 DECREF(sig_list[SIGINT].func);
166 sig_list[SIGINT].func = default_int_object;
167 INCREF(default_int_object);
168 signal(SIGINT, &signal_handler);
169 }
170
171#ifdef SIGHUP
172 x = newintobject(SIGHUP);
173 dictinsert(d, "SIGHUP", x);
174#endif
175#ifdef SIGINT
176 x = newintobject(SIGINT);
177 dictinsert(d, "SIGINT", x);
178#endif
179#ifdef SIGQUIT
180 x = newintobject(SIGQUIT);
181 dictinsert(d, "SIGQUIT", x);
182#endif
183#ifdef SIGILL
184 x = newintobject(SIGILL);
185 dictinsert(d, "SIGILL", x);
186#endif
187#ifdef SIGTRAP
188 x = newintobject(SIGTRAP);
189 dictinsert(d, "SIGTRAP", x);
190#endif
191#ifdef SIGIOT
192 x = newintobject(SIGIOT);
193 dictinsert(d, "SIGIOT", x);
194#endif
195#ifdef SIGABRT
196 x = newintobject(SIGABRT);
197 dictinsert(d, "SIGABRT", x);
198#endif
199#ifdef SIGEMT
200 x = newintobject(SIGEMT);
201 dictinsert(d, "SIGEMT", x);
202#endif
203#ifdef SIGFPE
204 x = newintobject(SIGFPE);
205 dictinsert(d, "SIGFPE", x);
206#endif
207#ifdef SIGKILL
208 x = newintobject(SIGKILL);
209 dictinsert(d, "SIGKILL", x);
210#endif
211#ifdef SIGBUS
212 x = newintobject(SIGBUS);
213 dictinsert(d, "SIGBUS", x);
214#endif
215#ifdef SIGSEGV
216 x = newintobject(SIGSEGV);
217 dictinsert(d, "SIGSEGV", x);
218#endif
219#ifdef SIGSYS
220 x = newintobject(SIGSYS);
221 dictinsert(d, "SIGSYS", x);
222#endif
223#ifdef SIGPIPE
224 x = newintobject(SIGPIPE);
225 dictinsert(d, "SIGPIPE", x);
226#endif
227#ifdef SIGALRM
228 x = newintobject(SIGALRM);
229 dictinsert(d, "SIGALRM", x);
230#endif
231#ifdef SIGTERM
232 x = newintobject(SIGTERM);
233 dictinsert(d, "SIGTERM", x);
234#endif
235#ifdef SIGUSR1
236 x = newintobject(SIGUSR1);
237 dictinsert(d, "SIGUSR1", x);
238#endif
239#ifdef SIGUSR2
240 x = newintobject(SIGUSR2);
241 dictinsert(d, "SIGUSR2", x);
242#endif
243#ifdef SIGCLD
244 x = newintobject(SIGCLD);
245 dictinsert(d, "SIGCLD", x);
246#endif
247#ifdef SIGCHLD
248 x = newintobject(SIGCHLD);
249 dictinsert(d, "SIGCHLD", x);
250#endif
251#ifdef SIGPWR
252 x = newintobject(SIGPWR);
253 dictinsert(d, "SIGPWR", x);
254#endif
255#ifdef SIGIO
256 x = newintobject(SIGIO);
257 dictinsert(d, "SIGIO", x);
258#endif
259#ifdef SIGURG
260 x = newintobject(SIGURG);
261 dictinsert(d, "SIGURG", x);
262#endif
263#ifdef SIGWINCH
264 x = newintobject(SIGWINCH);
265 dictinsert(d, "SIGWINCH", x);
266#endif
267#ifdef SIGPOLL
268 x = newintobject(SIGPOLL);
269 dictinsert(d, "SIGPOLL", x);
270#endif
271#ifdef SIGSTOP
272 x = newintobject(SIGSTOP);
273 dictinsert(d, "SIGSTOP", x);
274#endif
275#ifdef SIGTSTP
276 x = newintobject(SIGTSTP);
277 dictinsert(d, "SIGTSTP", x);
278#endif
279#ifdef SIGCONT
280 x = newintobject(SIGCONT);
281 dictinsert(d, "SIGCONT", x);
282#endif
283#ifdef SIGTTIN
284 x = newintobject(SIGTTIN);
285 dictinsert(d, "SIGTTIN", x);
286#endif
287#ifdef SIGTTOU
288 x = newintobject(SIGTTOU);
289 dictinsert(d, "SIGTTOU", x);
290#endif
291#ifdef SIGVTALRM
292 x = newintobject(SIGVTALRM);
293 dictinsert(d, "SIGVTALRM", x);
294#endif
295#ifdef SIGPROF
296 x = newintobject(SIGPROF);
297 dictinsert(d, "SIGPROF", x);
298#endif
299#ifdef SIGCPU
300 x = newintobject(SIGCPU);
301 dictinsert(d, "SIGCPU", x);
302#endif
303#ifdef SIGFSZ
304 x = newintobject(SIGFSZ);
305 dictinsert(d, "SIGFSZ", x);
306#endif
307 /* Check for errors */
308 if (err_occurred())
309 fatal("can't initialize module signal");
310}
311
312int
313sigcheck()
314{
315 int i;
316 object *f = getframe();
317 if (f == NULL)
318 f = None;
319 for (i = 1; i < NSIG; i++) {
320 if (sig_list[i].tripped) {
321 object *arglist, *result;
322 sig_list[i].tripped = 0;
323 arglist = mkvalue("(iO)", i, f);
324 if (arglist == NULL)
325 result = NULL;
326 else {
327 result = call_object(sig_list[i].func,arglist);
328 DECREF(arglist);
329 }
330 if (result == NULL) {
331 return 1;
332 } else {
333 DECREF(result);
334 }
335 }
336 }
337 return 0;
338}
339
340/* Replacement for intrcheck.c functionality */
341
342void
343initintr()
344{
345 initsignal();
346}
347
348int
349intrcheck()
350{
351 if (!sigcheck())
352 return 0;
353 err_clear();
354 return 1;
355}