|
1 |
|
2 /* Signal module -- many thanks to Lance Ellinghaus */ |
|
3 |
|
4 /* XXX Signals should be recorded per thread, now we have thread state. */ |
|
5 |
|
6 #include "Python.h" |
|
7 #include "intrcheck.h" |
|
8 |
|
9 #ifdef MS_WINDOWS |
|
10 #include <process.h> |
|
11 #endif |
|
12 |
|
13 #include <signal.h> |
|
14 |
|
15 #include <sys/stat.h> |
|
16 #ifdef HAVE_SYS_TIME_H |
|
17 #include <sys/time.h> |
|
18 #endif |
|
19 |
|
20 #ifndef SIG_ERR |
|
21 #define SIG_ERR ((PyOS_sighandler_t)(-1)) |
|
22 #endif |
|
23 |
|
24 #if defined(PYOS_OS2) && !defined(PYCC_GCC) |
|
25 #define NSIG 12 |
|
26 #include <process.h> |
|
27 #endif |
|
28 |
|
29 #ifndef NSIG |
|
30 # if defined(_NSIG) |
|
31 # define NSIG _NSIG /* For BSD/SysV */ |
|
32 # elif defined(_SIGMAX) |
|
33 # define NSIG (_SIGMAX + 1) /* For QNX */ |
|
34 # elif defined(SIGMAX) |
|
35 # define NSIG (SIGMAX + 1) /* For djgpp */ |
|
36 # else |
|
37 # define NSIG 64 /* Use a reasonable default value */ |
|
38 # endif |
|
39 #endif |
|
40 |
|
41 |
|
42 /* |
|
43 NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS |
|
44 |
|
45 When threads are supported, we want the following semantics: |
|
46 |
|
47 - only the main thread can set a signal handler |
|
48 - any thread can get a signal handler |
|
49 - signals are only delivered to the main thread |
|
50 |
|
51 I.e. we don't support "synchronous signals" like SIGFPE (catching |
|
52 this doesn't make much sense in Python anyway) nor do we support |
|
53 signals as a means of inter-thread communication, since not all |
|
54 thread implementations support that (at least our thread library |
|
55 doesn't). |
|
56 |
|
57 We still have the problem that in some implementations signals |
|
58 generated by the keyboard (e.g. SIGINT) are delivered to all |
|
59 threads (e.g. SGI), while in others (e.g. Solaris) such signals are |
|
60 delivered to one random thread (an intermediate possibility would |
|
61 be to deliver it to the main thread -- POSIX?). For now, we have |
|
62 a working implementation that works in all three cases -- the |
|
63 handler ignores signals if getpid() isn't the same as in the main |
|
64 thread. XXX This is a hack. |
|
65 |
|
66 GNU pth is a user-space threading library, and as such, all threads |
|
67 run within the same process. In this case, if the currently running |
|
68 thread is not the main_thread, send the signal to the main_thread. |
|
69 */ |
|
70 |
|
71 #ifdef WITH_THREAD |
|
72 #include <sys/types.h> /* For pid_t */ |
|
73 #include "pythread.h" |
|
74 static long main_thread; |
|
75 static pid_t main_pid; |
|
76 #endif |
|
77 |
|
78 static struct { |
|
79 int tripped; |
|
80 PyObject *func; |
|
81 } Handlers[NSIG]; |
|
82 |
|
83 static sig_atomic_t wakeup_fd = -1; |
|
84 |
|
85 /* Speed up sigcheck() when none tripped */ |
|
86 static volatile sig_atomic_t is_tripped = 0; |
|
87 |
|
88 static PyObject *DefaultHandler; |
|
89 static PyObject *IgnoreHandler; |
|
90 static PyObject *IntHandler; |
|
91 |
|
92 /* On Solaris 8, gcc will produce a warning that the function |
|
93 declaration is not a prototype. This is caused by the definition of |
|
94 SIG_DFL as (void (*)())0; the correct declaration would have been |
|
95 (void (*)(int))0. */ |
|
96 |
|
97 static PyOS_sighandler_t old_siginthandler = SIG_DFL; |
|
98 |
|
99 #ifdef HAVE_GETITIMER |
|
100 static PyObject *ItimerError; |
|
101 |
|
102 /* auxiliary functions for setitimer/getitimer */ |
|
103 static void |
|
104 timeval_from_double(double d, struct timeval *tv) |
|
105 { |
|
106 tv->tv_sec = floor(d); |
|
107 tv->tv_usec = fmod(d, 1.0) * 1000000.0; |
|
108 } |
|
109 |
|
110 Py_LOCAL_INLINE(double) |
|
111 double_from_timeval(struct timeval *tv) |
|
112 { |
|
113 return tv->tv_sec + (double)(tv->tv_usec / 1000000.0); |
|
114 } |
|
115 |
|
116 static PyObject * |
|
117 itimer_retval(struct itimerval *iv) |
|
118 { |
|
119 PyObject *r, *v; |
|
120 |
|
121 r = PyTuple_New(2); |
|
122 if (r == NULL) |
|
123 return NULL; |
|
124 |
|
125 if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) { |
|
126 Py_DECREF(r); |
|
127 return NULL; |
|
128 } |
|
129 |
|
130 PyTuple_SET_ITEM(r, 0, v); |
|
131 |
|
132 if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) { |
|
133 Py_DECREF(r); |
|
134 return NULL; |
|
135 } |
|
136 |
|
137 PyTuple_SET_ITEM(r, 1, v); |
|
138 |
|
139 return r; |
|
140 } |
|
141 #endif |
|
142 |
|
143 static PyObject * |
|
144 signal_default_int_handler(PyObject *self, PyObject *args) |
|
145 { |
|
146 PyErr_SetNone(PyExc_KeyboardInterrupt); |
|
147 return NULL; |
|
148 } |
|
149 |
|
150 PyDoc_STRVAR(default_int_handler_doc, |
|
151 "default_int_handler(...)\n\ |
|
152 \n\ |
|
153 The default handler for SIGINT installed by Python.\n\ |
|
154 It raises KeyboardInterrupt."); |
|
155 |
|
156 |
|
157 static int |
|
158 checksignals_witharg(void * unused) |
|
159 { |
|
160 return PyErr_CheckSignals(); |
|
161 } |
|
162 |
|
163 static void |
|
164 signal_handler(int sig_num) |
|
165 { |
|
166 #ifdef WITH_THREAD |
|
167 #ifdef WITH_PTH |
|
168 if (PyThread_get_thread_ident() != main_thread) { |
|
169 pth_raise(*(pth_t *) main_thread, sig_num); |
|
170 return; |
|
171 } |
|
172 #endif |
|
173 /* See NOTES section above */ |
|
174 if (getpid() == main_pid) { |
|
175 #endif |
|
176 Handlers[sig_num].tripped = 1; |
|
177 /* Set is_tripped after setting .tripped, as it gets |
|
178 cleared in PyErr_CheckSignals() before .tripped. */ |
|
179 is_tripped = 1; |
|
180 Py_AddPendingCall(checksignals_witharg, NULL); |
|
181 if (wakeup_fd != -1) |
|
182 write(wakeup_fd, "\0", 1); |
|
183 #ifdef WITH_THREAD |
|
184 } |
|
185 #endif |
|
186 #ifdef SIGCHLD |
|
187 if (sig_num == SIGCHLD) { |
|
188 /* To avoid infinite recursion, this signal remains |
|
189 reset until explicit re-instated. |
|
190 Don't clear the 'func' field as it is our pointer |
|
191 to the Python handler... */ |
|
192 return; |
|
193 } |
|
194 #endif |
|
195 PyOS_setsig(sig_num, signal_handler); |
|
196 } |
|
197 |
|
198 |
|
199 #ifdef HAVE_ALARM |
|
200 static PyObject * |
|
201 signal_alarm(PyObject *self, PyObject *args) |
|
202 { |
|
203 int t; |
|
204 if (!PyArg_ParseTuple(args, "i:alarm", &t)) |
|
205 return NULL; |
|
206 /* alarm() returns the number of seconds remaining */ |
|
207 return PyInt_FromLong((long)alarm(t)); |
|
208 } |
|
209 |
|
210 PyDoc_STRVAR(alarm_doc, |
|
211 "alarm(seconds)\n\ |
|
212 \n\ |
|
213 Arrange for SIGALRM to arrive after the given number of seconds."); |
|
214 #endif |
|
215 |
|
216 #ifdef HAVE_PAUSE |
|
217 static PyObject * |
|
218 signal_pause(PyObject *self) |
|
219 { |
|
220 Py_BEGIN_ALLOW_THREADS |
|
221 (void)pause(); |
|
222 Py_END_ALLOW_THREADS |
|
223 /* make sure that any exceptions that got raised are propagated |
|
224 * back into Python |
|
225 */ |
|
226 if (PyErr_CheckSignals()) |
|
227 return NULL; |
|
228 |
|
229 Py_INCREF(Py_None); |
|
230 return Py_None; |
|
231 } |
|
232 PyDoc_STRVAR(pause_doc, |
|
233 "pause()\n\ |
|
234 \n\ |
|
235 Wait until a signal arrives."); |
|
236 |
|
237 #endif |
|
238 |
|
239 |
|
240 static PyObject * |
|
241 signal_signal(PyObject *self, PyObject *args) |
|
242 { |
|
243 PyObject *obj; |
|
244 int sig_num; |
|
245 PyObject *old_handler; |
|
246 void (*func)(int); |
|
247 if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj)) |
|
248 return NULL; |
|
249 #ifdef WITH_THREAD |
|
250 if (PyThread_get_thread_ident() != main_thread) { |
|
251 PyErr_SetString(PyExc_ValueError, |
|
252 "signal only works in main thread"); |
|
253 return NULL; |
|
254 } |
|
255 #endif |
|
256 if (sig_num < 1 || sig_num >= NSIG) { |
|
257 PyErr_SetString(PyExc_ValueError, |
|
258 "signal number out of range"); |
|
259 return NULL; |
|
260 } |
|
261 if (obj == IgnoreHandler) |
|
262 func = SIG_IGN; |
|
263 else if (obj == DefaultHandler) |
|
264 func = SIG_DFL; |
|
265 else if (!PyCallable_Check(obj)) { |
|
266 PyErr_SetString(PyExc_TypeError, |
|
267 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object"); |
|
268 return NULL; |
|
269 } |
|
270 else |
|
271 func = signal_handler; |
|
272 if (PyOS_setsig(sig_num, func) == SIG_ERR) { |
|
273 PyErr_SetFromErrno(PyExc_RuntimeError); |
|
274 return NULL; |
|
275 } |
|
276 old_handler = Handlers[sig_num].func; |
|
277 Handlers[sig_num].tripped = 0; |
|
278 Py_INCREF(obj); |
|
279 Handlers[sig_num].func = obj; |
|
280 return old_handler; |
|
281 } |
|
282 |
|
283 PyDoc_STRVAR(signal_doc, |
|
284 "signal(sig, action) -> action\n\ |
|
285 \n\ |
|
286 Set the action for the given signal. The action can be SIG_DFL,\n\ |
|
287 SIG_IGN, or a callable Python object. The previous action is\n\ |
|
288 returned. See getsignal() for possible return values.\n\ |
|
289 \n\ |
|
290 *** IMPORTANT NOTICE ***\n\ |
|
291 A signal handler function is called with two arguments:\n\ |
|
292 the first is the signal number, the second is the interrupted stack frame."); |
|
293 |
|
294 |
|
295 static PyObject * |
|
296 signal_getsignal(PyObject *self, PyObject *args) |
|
297 { |
|
298 int sig_num; |
|
299 PyObject *old_handler; |
|
300 if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num)) |
|
301 return NULL; |
|
302 if (sig_num < 1 || sig_num >= NSIG) { |
|
303 PyErr_SetString(PyExc_ValueError, |
|
304 "signal number out of range"); |
|
305 return NULL; |
|
306 } |
|
307 old_handler = Handlers[sig_num].func; |
|
308 Py_INCREF(old_handler); |
|
309 return old_handler; |
|
310 } |
|
311 |
|
312 PyDoc_STRVAR(getsignal_doc, |
|
313 "getsignal(sig) -> action\n\ |
|
314 \n\ |
|
315 Return the current action for the given signal. The return value can be:\n\ |
|
316 SIG_IGN -- if the signal is being ignored\n\ |
|
317 SIG_DFL -- if the default action for the signal is in effect\n\ |
|
318 None -- if an unknown handler is in effect\n\ |
|
319 anything else -- the callable Python object used as a handler"); |
|
320 |
|
321 #ifdef HAVE_SIGINTERRUPT |
|
322 PyDoc_STRVAR(siginterrupt_doc, |
|
323 "siginterrupt(sig, flag) -> None\n\ |
|
324 change system call restart behaviour: if flag is False, system calls\n\ |
|
325 will be restarted when interrupted by signal sig, else system calls\n\ |
|
326 will be interrupted."); |
|
327 |
|
328 static PyObject * |
|
329 signal_siginterrupt(PyObject *self, PyObject *args) |
|
330 { |
|
331 int sig_num; |
|
332 int flag; |
|
333 |
|
334 if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag)) |
|
335 return NULL; |
|
336 if (sig_num < 1 || sig_num >= NSIG) { |
|
337 PyErr_SetString(PyExc_ValueError, |
|
338 "signal number out of range"); |
|
339 return NULL; |
|
340 } |
|
341 if (siginterrupt(sig_num, flag)<0) { |
|
342 PyErr_SetFromErrno(PyExc_RuntimeError); |
|
343 return NULL; |
|
344 } |
|
345 |
|
346 Py_INCREF(Py_None); |
|
347 return Py_None; |
|
348 } |
|
349 |
|
350 #endif |
|
351 |
|
352 static PyObject * |
|
353 signal_set_wakeup_fd(PyObject *self, PyObject *args) |
|
354 { |
|
355 struct stat buf; |
|
356 int fd, old_fd; |
|
357 if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd)) |
|
358 return NULL; |
|
359 #ifdef WITH_THREAD |
|
360 if (PyThread_get_thread_ident() != main_thread) { |
|
361 PyErr_SetString(PyExc_ValueError, |
|
362 "set_wakeup_fd only works in main thread"); |
|
363 return NULL; |
|
364 } |
|
365 #endif |
|
366 if (fd != -1 && fstat(fd, &buf) != 0) { |
|
367 PyErr_SetString(PyExc_ValueError, "invalid fd"); |
|
368 return NULL; |
|
369 } |
|
370 old_fd = wakeup_fd; |
|
371 wakeup_fd = fd; |
|
372 return PyLong_FromLong(old_fd); |
|
373 } |
|
374 |
|
375 PyDoc_STRVAR(set_wakeup_fd_doc, |
|
376 "set_wakeup_fd(fd) -> fd\n\ |
|
377 \n\ |
|
378 Sets the fd to be written to (with '\\0') when a signal\n\ |
|
379 comes in. A library can use this to wakeup select or poll.\n\ |
|
380 The previous fd is returned.\n\ |
|
381 \n\ |
|
382 The fd must be non-blocking."); |
|
383 |
|
384 /* C API for the same, without all the error checking */ |
|
385 int |
|
386 PySignal_SetWakeupFd(int fd) |
|
387 { |
|
388 int old_fd = wakeup_fd; |
|
389 if (fd < 0) |
|
390 fd = -1; |
|
391 wakeup_fd = fd; |
|
392 return old_fd; |
|
393 } |
|
394 |
|
395 |
|
396 #ifdef HAVE_SETITIMER |
|
397 static PyObject * |
|
398 signal_setitimer(PyObject *self, PyObject *args) |
|
399 { |
|
400 double first; |
|
401 double interval = 0; |
|
402 int which; |
|
403 struct itimerval new, old; |
|
404 |
|
405 if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval)) |
|
406 return NULL; |
|
407 |
|
408 timeval_from_double(first, &new.it_value); |
|
409 timeval_from_double(interval, &new.it_interval); |
|
410 /* Let OS check "which" value */ |
|
411 if (setitimer(which, &new, &old) != 0) { |
|
412 PyErr_SetFromErrno(ItimerError); |
|
413 return NULL; |
|
414 } |
|
415 |
|
416 return itimer_retval(&old); |
|
417 } |
|
418 |
|
419 PyDoc_STRVAR(setitimer_doc, |
|
420 "setitimer(which, seconds[, interval])\n\ |
|
421 \n\ |
|
422 Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\ |
|
423 or ITIMER_PROF) to fire after value seconds and after\n\ |
|
424 that every interval seconds.\n\ |
|
425 The itimer can be cleared by setting seconds to zero.\n\ |
|
426 \n\ |
|
427 Returns old values as a tuple: (delay, interval)."); |
|
428 #endif |
|
429 |
|
430 |
|
431 #ifdef HAVE_GETITIMER |
|
432 static PyObject * |
|
433 signal_getitimer(PyObject *self, PyObject *args) |
|
434 { |
|
435 int which; |
|
436 struct itimerval old; |
|
437 |
|
438 if (!PyArg_ParseTuple(args, "i:getitimer", &which)) |
|
439 return NULL; |
|
440 |
|
441 if (getitimer(which, &old) != 0) { |
|
442 PyErr_SetFromErrno(ItimerError); |
|
443 return NULL; |
|
444 } |
|
445 |
|
446 return itimer_retval(&old); |
|
447 } |
|
448 |
|
449 PyDoc_STRVAR(getitimer_doc, |
|
450 "getitimer(which)\n\ |
|
451 \n\ |
|
452 Returns current value of given itimer."); |
|
453 #endif |
|
454 |
|
455 |
|
456 /* List of functions defined in the module */ |
|
457 static PyMethodDef signal_methods[] = { |
|
458 #ifdef HAVE_ALARM |
|
459 {"alarm", signal_alarm, METH_VARARGS, alarm_doc}, |
|
460 #endif |
|
461 #ifdef HAVE_SETITIMER |
|
462 {"setitimer", signal_setitimer, METH_VARARGS, setitimer_doc}, |
|
463 #endif |
|
464 #ifdef HAVE_GETITIMER |
|
465 {"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc}, |
|
466 #endif |
|
467 {"signal", signal_signal, METH_VARARGS, signal_doc}, |
|
468 {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, |
|
469 {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, |
|
470 #ifdef HAVE_SIGINTERRUPT |
|
471 {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, |
|
472 #endif |
|
473 #ifdef HAVE_PAUSE |
|
474 {"pause", (PyCFunction)signal_pause, |
|
475 METH_NOARGS,pause_doc}, |
|
476 #endif |
|
477 {"default_int_handler", signal_default_int_handler, |
|
478 METH_VARARGS, default_int_handler_doc}, |
|
479 {NULL, NULL} /* sentinel */ |
|
480 }; |
|
481 |
|
482 |
|
483 PyDoc_STRVAR(module_doc, |
|
484 "This module provides mechanisms to use signal handlers in Python.\n\ |
|
485 \n\ |
|
486 Functions:\n\ |
|
487 \n\ |
|
488 alarm() -- cause SIGALRM after a specified time [Unix only]\n\ |
|
489 setitimer() -- cause a signal (described below) after a specified\n\ |
|
490 float time and the timer may restart then [Unix only]\n\ |
|
491 getitimer() -- get current value of timer [Unix only]\n\ |
|
492 signal() -- set the action for a given signal\n\ |
|
493 getsignal() -- get the signal action for a given signal\n\ |
|
494 pause() -- wait until a signal arrives [Unix only]\n\ |
|
495 default_int_handler() -- default SIGINT handler\n\ |
|
496 \n\ |
|
497 signal constants:\n\ |
|
498 SIG_DFL -- used to refer to the system default handler\n\ |
|
499 SIG_IGN -- used to ignore the signal\n\ |
|
500 NSIG -- number of defined signals\n\ |
|
501 SIGINT, SIGTERM, etc. -- signal numbers\n\ |
|
502 \n\ |
|
503 itimer constants:\n\ |
|
504 ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\ |
|
505 expiration\n\ |
|
506 ITIMER_VIRTUAL -- decrements only when the process is executing,\n\ |
|
507 and delivers SIGVTALRM upon expiration\n\ |
|
508 ITIMER_PROF -- decrements both when the process is executing and\n\ |
|
509 when the system is executing on behalf of the process.\n\ |
|
510 Coupled with ITIMER_VIRTUAL, this timer is usually\n\ |
|
511 used to profile the time spent by the application\n\ |
|
512 in user and kernel space. SIGPROF is delivered upon\n\ |
|
513 expiration.\n\ |
|
514 \n\n\ |
|
515 *** IMPORTANT NOTICE ***\n\ |
|
516 A signal handler function is called with two arguments:\n\ |
|
517 the first is the signal number, the second is the interrupted stack frame."); |
|
518 |
|
519 PyMODINIT_FUNC |
|
520 initsignal(void) |
|
521 { |
|
522 PyObject *m, *d, *x; |
|
523 int i; |
|
524 |
|
525 #ifdef WITH_THREAD |
|
526 main_thread = PyThread_get_thread_ident(); |
|
527 main_pid = getpid(); |
|
528 #endif |
|
529 |
|
530 /* Create the module and add the functions */ |
|
531 m = Py_InitModule3("signal", signal_methods, module_doc); |
|
532 if (m == NULL) |
|
533 return; |
|
534 |
|
535 /* Add some symbolic constants to the module */ |
|
536 d = PyModule_GetDict(m); |
|
537 |
|
538 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); |
|
539 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0) |
|
540 goto finally; |
|
541 |
|
542 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); |
|
543 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0) |
|
544 goto finally; |
|
545 |
|
546 x = PyInt_FromLong((long)NSIG); |
|
547 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0) |
|
548 goto finally; |
|
549 Py_DECREF(x); |
|
550 |
|
551 x = IntHandler = PyDict_GetItemString(d, "default_int_handler"); |
|
552 if (!x) |
|
553 goto finally; |
|
554 Py_INCREF(IntHandler); |
|
555 |
|
556 Handlers[0].tripped = 0; |
|
557 for (i = 1; i < NSIG; i++) { |
|
558 void (*t)(int); |
|
559 t = PyOS_getsig(i); |
|
560 Handlers[i].tripped = 0; |
|
561 if (t == SIG_DFL) |
|
562 Handlers[i].func = DefaultHandler; |
|
563 else if (t == SIG_IGN) |
|
564 Handlers[i].func = IgnoreHandler; |
|
565 else |
|
566 Handlers[i].func = Py_None; /* None of our business */ |
|
567 Py_INCREF(Handlers[i].func); |
|
568 } |
|
569 if (Handlers[SIGINT].func == DefaultHandler) { |
|
570 /* Install default int handler */ |
|
571 Py_INCREF(IntHandler); |
|
572 Py_DECREF(Handlers[SIGINT].func); |
|
573 Handlers[SIGINT].func = IntHandler; |
|
574 old_siginthandler = PyOS_setsig(SIGINT, signal_handler); |
|
575 } |
|
576 |
|
577 #ifdef SIGHUP |
|
578 x = PyInt_FromLong(SIGHUP); |
|
579 PyDict_SetItemString(d, "SIGHUP", x); |
|
580 Py_XDECREF(x); |
|
581 #endif |
|
582 #ifdef SIGINT |
|
583 x = PyInt_FromLong(SIGINT); |
|
584 PyDict_SetItemString(d, "SIGINT", x); |
|
585 Py_XDECREF(x); |
|
586 #endif |
|
587 #ifdef SIGBREAK |
|
588 x = PyInt_FromLong(SIGBREAK); |
|
589 PyDict_SetItemString(d, "SIGBREAK", x); |
|
590 Py_XDECREF(x); |
|
591 #endif |
|
592 #ifdef SIGQUIT |
|
593 x = PyInt_FromLong(SIGQUIT); |
|
594 PyDict_SetItemString(d, "SIGQUIT", x); |
|
595 Py_XDECREF(x); |
|
596 #endif |
|
597 #ifdef SIGILL |
|
598 x = PyInt_FromLong(SIGILL); |
|
599 PyDict_SetItemString(d, "SIGILL", x); |
|
600 Py_XDECREF(x); |
|
601 #endif |
|
602 #ifdef SIGTRAP |
|
603 x = PyInt_FromLong(SIGTRAP); |
|
604 PyDict_SetItemString(d, "SIGTRAP", x); |
|
605 Py_XDECREF(x); |
|
606 #endif |
|
607 #ifdef SIGIOT |
|
608 x = PyInt_FromLong(SIGIOT); |
|
609 PyDict_SetItemString(d, "SIGIOT", x); |
|
610 Py_XDECREF(x); |
|
611 #endif |
|
612 #ifdef SIGABRT |
|
613 x = PyInt_FromLong(SIGABRT); |
|
614 PyDict_SetItemString(d, "SIGABRT", x); |
|
615 Py_XDECREF(x); |
|
616 #endif |
|
617 #ifdef SIGEMT |
|
618 x = PyInt_FromLong(SIGEMT); |
|
619 PyDict_SetItemString(d, "SIGEMT", x); |
|
620 Py_XDECREF(x); |
|
621 #endif |
|
622 #ifdef SIGFPE |
|
623 x = PyInt_FromLong(SIGFPE); |
|
624 PyDict_SetItemString(d, "SIGFPE", x); |
|
625 Py_XDECREF(x); |
|
626 #endif |
|
627 #ifdef SIGKILL |
|
628 x = PyInt_FromLong(SIGKILL); |
|
629 PyDict_SetItemString(d, "SIGKILL", x); |
|
630 Py_XDECREF(x); |
|
631 #endif |
|
632 #ifdef SIGBUS |
|
633 x = PyInt_FromLong(SIGBUS); |
|
634 PyDict_SetItemString(d, "SIGBUS", x); |
|
635 Py_XDECREF(x); |
|
636 #endif |
|
637 #ifdef SIGSEGV |
|
638 x = PyInt_FromLong(SIGSEGV); |
|
639 PyDict_SetItemString(d, "SIGSEGV", x); |
|
640 Py_XDECREF(x); |
|
641 #endif |
|
642 #ifdef SIGSYS |
|
643 x = PyInt_FromLong(SIGSYS); |
|
644 PyDict_SetItemString(d, "SIGSYS", x); |
|
645 Py_XDECREF(x); |
|
646 #endif |
|
647 #ifdef SIGPIPE |
|
648 x = PyInt_FromLong(SIGPIPE); |
|
649 PyDict_SetItemString(d, "SIGPIPE", x); |
|
650 Py_XDECREF(x); |
|
651 #endif |
|
652 #ifdef SIGALRM |
|
653 x = PyInt_FromLong(SIGALRM); |
|
654 PyDict_SetItemString(d, "SIGALRM", x); |
|
655 Py_XDECREF(x); |
|
656 #endif |
|
657 #ifdef SIGTERM |
|
658 x = PyInt_FromLong(SIGTERM); |
|
659 PyDict_SetItemString(d, "SIGTERM", x); |
|
660 Py_XDECREF(x); |
|
661 #endif |
|
662 #ifdef SIGUSR1 |
|
663 x = PyInt_FromLong(SIGUSR1); |
|
664 PyDict_SetItemString(d, "SIGUSR1", x); |
|
665 Py_XDECREF(x); |
|
666 #endif |
|
667 #ifdef SIGUSR2 |
|
668 x = PyInt_FromLong(SIGUSR2); |
|
669 PyDict_SetItemString(d, "SIGUSR2", x); |
|
670 Py_XDECREF(x); |
|
671 #endif |
|
672 #ifdef SIGCLD |
|
673 x = PyInt_FromLong(SIGCLD); |
|
674 PyDict_SetItemString(d, "SIGCLD", x); |
|
675 Py_XDECREF(x); |
|
676 #endif |
|
677 #ifdef SIGCHLD |
|
678 x = PyInt_FromLong(SIGCHLD); |
|
679 PyDict_SetItemString(d, "SIGCHLD", x); |
|
680 Py_XDECREF(x); |
|
681 #endif |
|
682 #ifdef SIGPWR |
|
683 x = PyInt_FromLong(SIGPWR); |
|
684 PyDict_SetItemString(d, "SIGPWR", x); |
|
685 Py_XDECREF(x); |
|
686 #endif |
|
687 #ifdef SIGIO |
|
688 x = PyInt_FromLong(SIGIO); |
|
689 PyDict_SetItemString(d, "SIGIO", x); |
|
690 Py_XDECREF(x); |
|
691 #endif |
|
692 #ifdef SIGURG |
|
693 x = PyInt_FromLong(SIGURG); |
|
694 PyDict_SetItemString(d, "SIGURG", x); |
|
695 Py_XDECREF(x); |
|
696 #endif |
|
697 #ifdef SIGWINCH |
|
698 x = PyInt_FromLong(SIGWINCH); |
|
699 PyDict_SetItemString(d, "SIGWINCH", x); |
|
700 Py_XDECREF(x); |
|
701 #endif |
|
702 #ifdef SIGPOLL |
|
703 x = PyInt_FromLong(SIGPOLL); |
|
704 PyDict_SetItemString(d, "SIGPOLL", x); |
|
705 Py_XDECREF(x); |
|
706 #endif |
|
707 #ifdef SIGSTOP |
|
708 x = PyInt_FromLong(SIGSTOP); |
|
709 PyDict_SetItemString(d, "SIGSTOP", x); |
|
710 Py_XDECREF(x); |
|
711 #endif |
|
712 #ifdef SIGTSTP |
|
713 x = PyInt_FromLong(SIGTSTP); |
|
714 PyDict_SetItemString(d, "SIGTSTP", x); |
|
715 Py_XDECREF(x); |
|
716 #endif |
|
717 #ifdef SIGCONT |
|
718 x = PyInt_FromLong(SIGCONT); |
|
719 PyDict_SetItemString(d, "SIGCONT", x); |
|
720 Py_XDECREF(x); |
|
721 #endif |
|
722 #ifdef SIGTTIN |
|
723 x = PyInt_FromLong(SIGTTIN); |
|
724 PyDict_SetItemString(d, "SIGTTIN", x); |
|
725 Py_XDECREF(x); |
|
726 #endif |
|
727 #ifdef SIGTTOU |
|
728 x = PyInt_FromLong(SIGTTOU); |
|
729 PyDict_SetItemString(d, "SIGTTOU", x); |
|
730 Py_XDECREF(x); |
|
731 #endif |
|
732 #ifdef SIGVTALRM |
|
733 x = PyInt_FromLong(SIGVTALRM); |
|
734 PyDict_SetItemString(d, "SIGVTALRM", x); |
|
735 Py_XDECREF(x); |
|
736 #endif |
|
737 #ifdef SIGPROF |
|
738 x = PyInt_FromLong(SIGPROF); |
|
739 PyDict_SetItemString(d, "SIGPROF", x); |
|
740 Py_XDECREF(x); |
|
741 #endif |
|
742 #ifdef SIGXCPU |
|
743 x = PyInt_FromLong(SIGXCPU); |
|
744 PyDict_SetItemString(d, "SIGXCPU", x); |
|
745 Py_XDECREF(x); |
|
746 #endif |
|
747 #ifdef SIGXFSZ |
|
748 x = PyInt_FromLong(SIGXFSZ); |
|
749 PyDict_SetItemString(d, "SIGXFSZ", x); |
|
750 Py_XDECREF(x); |
|
751 #endif |
|
752 #ifdef SIGRTMIN |
|
753 x = PyInt_FromLong(SIGRTMIN); |
|
754 PyDict_SetItemString(d, "SIGRTMIN", x); |
|
755 Py_XDECREF(x); |
|
756 #endif |
|
757 #ifdef SIGRTMAX |
|
758 x = PyInt_FromLong(SIGRTMAX); |
|
759 PyDict_SetItemString(d, "SIGRTMAX", x); |
|
760 Py_XDECREF(x); |
|
761 #endif |
|
762 #ifdef SIGINFO |
|
763 x = PyInt_FromLong(SIGINFO); |
|
764 PyDict_SetItemString(d, "SIGINFO", x); |
|
765 Py_XDECREF(x); |
|
766 #endif |
|
767 |
|
768 #ifdef ITIMER_REAL |
|
769 x = PyLong_FromLong(ITIMER_REAL); |
|
770 PyDict_SetItemString(d, "ITIMER_REAL", x); |
|
771 Py_DECREF(x); |
|
772 #endif |
|
773 #ifdef ITIMER_VIRTUAL |
|
774 x = PyLong_FromLong(ITIMER_VIRTUAL); |
|
775 PyDict_SetItemString(d, "ITIMER_VIRTUAL", x); |
|
776 Py_DECREF(x); |
|
777 #endif |
|
778 #ifdef ITIMER_PROF |
|
779 x = PyLong_FromLong(ITIMER_PROF); |
|
780 PyDict_SetItemString(d, "ITIMER_PROF", x); |
|
781 Py_DECREF(x); |
|
782 #endif |
|
783 |
|
784 #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) |
|
785 ItimerError = PyErr_NewException("signal.ItimerError", |
|
786 PyExc_IOError, NULL); |
|
787 if (ItimerError != NULL) |
|
788 PyDict_SetItemString(d, "ItimerError", ItimerError); |
|
789 #endif |
|
790 |
|
791 if (!PyErr_Occurred()) |
|
792 return; |
|
793 |
|
794 /* Check for errors */ |
|
795 finally: |
|
796 return; |
|
797 } |
|
798 |
|
799 static void |
|
800 finisignal(void) |
|
801 { |
|
802 int i; |
|
803 PyObject *func; |
|
804 |
|
805 PyOS_setsig(SIGINT, old_siginthandler); |
|
806 old_siginthandler = SIG_DFL; |
|
807 |
|
808 for (i = 1; i < NSIG; i++) { |
|
809 func = Handlers[i].func; |
|
810 Handlers[i].tripped = 0; |
|
811 Handlers[i].func = NULL; |
|
812 if (i != SIGINT && func != NULL && func != Py_None && |
|
813 func != DefaultHandler && func != IgnoreHandler) |
|
814 PyOS_setsig(i, SIG_DFL); |
|
815 Py_XDECREF(func); |
|
816 } |
|
817 |
|
818 Py_XDECREF(IntHandler); |
|
819 IntHandler = NULL; |
|
820 Py_XDECREF(DefaultHandler); |
|
821 DefaultHandler = NULL; |
|
822 Py_XDECREF(IgnoreHandler); |
|
823 IgnoreHandler = NULL; |
|
824 } |
|
825 |
|
826 |
|
827 /* Declared in pyerrors.h */ |
|
828 int |
|
829 PyErr_CheckSignals(void) |
|
830 { |
|
831 int i; |
|
832 PyObject *f; |
|
833 |
|
834 if (!is_tripped) |
|
835 return 0; |
|
836 |
|
837 #ifdef WITH_THREAD |
|
838 if (PyThread_get_thread_ident() != main_thread) |
|
839 return 0; |
|
840 #endif |
|
841 |
|
842 /* |
|
843 * The is_stripped variable is meant to speed up the calls to |
|
844 * PyErr_CheckSignals (both directly or via pending calls) when no |
|
845 * signal has arrived. This variable is set to 1 when a signal arrives |
|
846 * and it is set to 0 here, when we know some signals arrived. This way |
|
847 * we can run the registered handlers with no signals blocked. |
|
848 * |
|
849 * NOTE: with this approach we can have a situation where is_tripped is |
|
850 * 1 but we have no more signals to handle (Handlers[i].tripped |
|
851 * is 0 for every signal i). This won't do us any harm (except |
|
852 * we're gonna spent some cycles for nothing). This happens when |
|
853 * we receive a signal i after we zero is_tripped and before we |
|
854 * check Handlers[i].tripped. |
|
855 */ |
|
856 is_tripped = 0; |
|
857 |
|
858 if (!(f = (PyObject *)PyEval_GetFrame())) |
|
859 f = Py_None; |
|
860 |
|
861 for (i = 1; i < NSIG; i++) { |
|
862 if (Handlers[i].tripped) { |
|
863 PyObject *result = NULL; |
|
864 PyObject *arglist = Py_BuildValue("(iO)", i, f); |
|
865 Handlers[i].tripped = 0; |
|
866 |
|
867 if (arglist) { |
|
868 result = PyEval_CallObject(Handlers[i].func, |
|
869 arglist); |
|
870 Py_DECREF(arglist); |
|
871 } |
|
872 if (!result) |
|
873 return -1; |
|
874 |
|
875 Py_DECREF(result); |
|
876 } |
|
877 } |
|
878 |
|
879 return 0; |
|
880 } |
|
881 |
|
882 |
|
883 /* Replacements for intrcheck.c functionality |
|
884 * Declared in pyerrors.h |
|
885 */ |
|
886 void |
|
887 PyErr_SetInterrupt(void) |
|
888 { |
|
889 is_tripped = 1; |
|
890 Handlers[SIGINT].tripped = 1; |
|
891 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL); |
|
892 } |
|
893 |
|
894 void |
|
895 PyOS_InitInterrupts(void) |
|
896 { |
|
897 initsignal(); |
|
898 _PyImport_FixupExtension("signal", "signal"); |
|
899 } |
|
900 |
|
901 void |
|
902 PyOS_FiniInterrupts(void) |
|
903 { |
|
904 finisignal(); |
|
905 } |
|
906 |
|
907 int |
|
908 PyOS_InterruptOccurred(void) |
|
909 { |
|
910 if (Handlers[SIGINT].tripped) { |
|
911 #ifdef WITH_THREAD |
|
912 if (PyThread_get_thread_ident() != main_thread) |
|
913 return 0; |
|
914 #endif |
|
915 Handlers[SIGINT].tripped = 0; |
|
916 return 1; |
|
917 } |
|
918 return 0; |
|
919 } |
|
920 |
|
921 void |
|
922 PyOS_AfterFork(void) |
|
923 { |
|
924 #ifdef WITH_THREAD |
|
925 PyEval_ReInitThreads(); |
|
926 main_thread = PyThread_get_thread_ident(); |
|
927 main_pid = getpid(); |
|
928 _PyImport_ReInitLock(); |
|
929 PyThread_ReInitTLS(); |
|
930 #endif |
|
931 } |