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