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