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 :
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 : #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
26 : # define PYPTHREAD_SIGMASK
27 : #endif
28 :
29 : #if defined(PYPTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H)
30 : # include <pthread.h>
31 : #endif
32 :
33 : #ifndef SIG_ERR
34 : #define SIG_ERR ((PyOS_sighandler_t)(-1))
35 : #endif
36 :
37 : #if defined(PYOS_OS2) && !defined(PYCC_GCC)
38 : #define NSIG 12
39 : #include <process.h>
40 : #endif
41 :
42 : #ifndef NSIG
43 : # if defined(_NSIG)
44 : # define NSIG _NSIG /* For BSD/SysV */
45 : # elif defined(_SIGMAX)
46 : # define NSIG (_SIGMAX + 1) /* For QNX */
47 : # elif defined(SIGMAX)
48 : # define NSIG (SIGMAX + 1) /* For djgpp */
49 : # else
50 : # define NSIG 64 /* Use a reasonable default value */
51 : # endif
52 : #endif
53 :
54 :
55 : /*
56 : NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
57 :
58 : When threads are supported, we want the following semantics:
59 :
60 : - only the main thread can set a signal handler
61 : - any thread can get a signal handler
62 : - signals are only delivered to the main thread
63 :
64 : I.e. we don't support "synchronous signals" like SIGFPE (catching
65 : this doesn't make much sense in Python anyway) nor do we support
66 : signals as a means of inter-thread communication, since not all
67 : thread implementations support that (at least our thread library
68 : doesn't).
69 :
70 : We still have the problem that in some implementations signals
71 : generated by the keyboard (e.g. SIGINT) are delivered to all
72 : threads (e.g. SGI), while in others (e.g. Solaris) such signals are
73 : delivered to one random thread (an intermediate possibility would
74 : be to deliver it to the main thread -- POSIX?). For now, we have
75 : a working implementation that works in all three cases -- the
76 : handler ignores signals if getpid() isn't the same as in the main
77 : thread. XXX This is a hack.
78 :
79 : GNU pth is a user-space threading library, and as such, all threads
80 : run within the same process. In this case, if the currently running
81 : thread is not the main_thread, send the signal to the main_thread.
82 : */
83 :
84 : #ifdef WITH_THREAD
85 : #include <sys/types.h> /* For pid_t */
86 : #include "pythread.h"
87 : static long main_thread;
88 : static pid_t main_pid;
89 : #endif
90 :
91 : static volatile struct {
92 : sig_atomic_t tripped;
93 : PyObject *func;
94 : } Handlers[NSIG];
95 :
96 : static volatile sig_atomic_t wakeup_fd = -1;
97 :
98 : /* Speed up sigcheck() when none tripped */
99 : static volatile sig_atomic_t is_tripped = 0;
100 :
101 : static PyObject *DefaultHandler;
102 : static PyObject *IgnoreHandler;
103 : static PyObject *IntHandler;
104 :
105 : /* On Solaris 8, gcc will produce a warning that the function
106 : declaration is not a prototype. This is caused by the definition of
107 : SIG_DFL as (void (*)())0; the correct declaration would have been
108 : (void (*)(int))0. */
109 :
110 : static PyOS_sighandler_t old_siginthandler = SIG_DFL;
111 :
112 : #ifdef MS_WINDOWS
113 : static HANDLE sigint_event = NULL;
114 : #endif
115 :
116 : #ifdef HAVE_GETITIMER
117 : static PyObject *ItimerError;
118 :
119 : /* auxiliary functions for setitimer/getitimer */
120 : static void
121 0 : timeval_from_double(double d, struct timeval *tv)
122 : {
123 0 : tv->tv_sec = floor(d);
124 0 : tv->tv_usec = fmod(d, 1.0) * 1000000.0;
125 0 : }
126 :
127 : Py_LOCAL_INLINE(double)
128 0 : double_from_timeval(struct timeval *tv)
129 : {
130 0 : return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
131 : }
132 :
133 : static PyObject *
134 0 : itimer_retval(struct itimerval *iv)
135 : {
136 : PyObject *r, *v;
137 :
138 0 : r = PyTuple_New(2);
139 0 : if (r == NULL)
140 0 : return NULL;
141 :
142 0 : if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) {
143 0 : Py_DECREF(r);
144 0 : return NULL;
145 : }
146 :
147 0 : PyTuple_SET_ITEM(r, 0, v);
148 :
149 0 : if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) {
150 0 : Py_DECREF(r);
151 0 : return NULL;
152 : }
153 :
154 0 : PyTuple_SET_ITEM(r, 1, v);
155 :
156 0 : return r;
157 : }
158 : #endif
159 :
160 : static PyObject *
161 0 : signal_default_int_handler(PyObject *self, PyObject *args)
162 : {
163 0 : PyErr_SetNone(PyExc_KeyboardInterrupt);
164 0 : return NULL;
165 : }
166 :
167 : PyDoc_STRVAR(default_int_handler_doc,
168 : "default_int_handler(...)\n\
169 : \n\
170 : The default handler for SIGINT installed by Python.\n\
171 : It raises KeyboardInterrupt.");
172 :
173 :
174 : static int
175 0 : checksignals_witharg(void * unused)
176 : {
177 0 : return PyErr_CheckSignals();
178 : }
179 :
180 : static void
181 0 : trip_signal(int sig_num)
182 : {
183 : unsigned char byte;
184 :
185 0 : Handlers[sig_num].tripped = 1;
186 0 : if (wakeup_fd != -1) {
187 0 : byte = (unsigned char)sig_num;
188 0 : write(wakeup_fd, &byte, 1);
189 : }
190 0 : if (is_tripped)
191 0 : return;
192 : /* Set is_tripped after setting .tripped, as it gets
193 : cleared in PyErr_CheckSignals() before .tripped. */
194 0 : is_tripped = 1;
195 0 : Py_AddPendingCall(checksignals_witharg, NULL);
196 : }
197 :
198 : static void
199 0 : signal_handler(int sig_num)
200 : {
201 0 : int save_errno = errno;
202 :
203 : #if defined(WITH_THREAD) && defined(WITH_PTH)
204 : if (PyThread_get_thread_ident() != main_thread) {
205 : pth_raise(*(pth_t *) main_thread, sig_num);
206 : }
207 : else
208 : #endif
209 : {
210 : #ifdef WITH_THREAD
211 : /* See NOTES section above */
212 0 : if (getpid() == main_pid)
213 : #endif
214 : {
215 0 : trip_signal(sig_num);
216 : }
217 :
218 : #ifndef HAVE_SIGACTION
219 : #ifdef SIGCHLD
220 : /* To avoid infinite recursion, this signal remains
221 : reset until explicit re-instated.
222 : Don't clear the 'func' field as it is our pointer
223 : to the Python handler... */
224 : if (sig_num != SIGCHLD)
225 : #endif
226 : /* If the handler was not set up with sigaction, reinstall it. See
227 : * Python/pythonrun.c for the implementation of PyOS_setsig which
228 : * makes this true. See also issue8354. */
229 : PyOS_setsig(sig_num, signal_handler);
230 : #endif
231 : }
232 :
233 : /* Issue #10311: asynchronously executing signal handlers should not
234 : mutate errno under the feet of unsuspecting C code. */
235 0 : errno = save_errno;
236 :
237 : #ifdef MS_WINDOWS
238 : if (sig_num == SIGINT)
239 : SetEvent(sigint_event);
240 : #endif
241 0 : }
242 :
243 :
244 : #ifdef HAVE_ALARM
245 : static PyObject *
246 0 : signal_alarm(PyObject *self, PyObject *args)
247 : {
248 : int t;
249 0 : if (!PyArg_ParseTuple(args, "i:alarm", &t))
250 0 : return NULL;
251 : /* alarm() returns the number of seconds remaining */
252 0 : return PyLong_FromLong((long)alarm(t));
253 : }
254 :
255 : PyDoc_STRVAR(alarm_doc,
256 : "alarm(seconds)\n\
257 : \n\
258 : Arrange for SIGALRM to arrive after the given number of seconds.");
259 : #endif
260 :
261 : #ifdef HAVE_PAUSE
262 : static PyObject *
263 0 : signal_pause(PyObject *self)
264 : {
265 0 : Py_BEGIN_ALLOW_THREADS
266 0 : (void)pause();
267 0 : Py_END_ALLOW_THREADS
268 : /* make sure that any exceptions that got raised are propagated
269 : * back into Python
270 : */
271 0 : if (PyErr_CheckSignals())
272 0 : return NULL;
273 :
274 0 : Py_INCREF(Py_None);
275 0 : return Py_None;
276 : }
277 : PyDoc_STRVAR(pause_doc,
278 : "pause()\n\
279 : \n\
280 : Wait until a signal arrives.");
281 :
282 : #endif
283 :
284 :
285 : static PyObject *
286 0 : signal_signal(PyObject *self, PyObject *args)
287 : {
288 : PyObject *obj;
289 : int sig_num;
290 : PyObject *old_handler;
291 : void (*func)(int);
292 0 : if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
293 0 : return NULL;
294 : #ifdef MS_WINDOWS
295 : /* Validate that sig_num is one of the allowable signals */
296 : switch (sig_num) {
297 : case SIGABRT: break;
298 : #ifdef SIGBREAK
299 : /* Issue #10003: SIGBREAK is not documented as permitted, but works
300 : and corresponds to CTRL_BREAK_EVENT. */
301 : case SIGBREAK: break;
302 : #endif
303 : case SIGFPE: break;
304 : case SIGILL: break;
305 : case SIGINT: break;
306 : case SIGSEGV: break;
307 : case SIGTERM: break;
308 : default:
309 : PyErr_SetString(PyExc_ValueError, "invalid signal value");
310 : return NULL;
311 : }
312 : #endif
313 : #ifdef WITH_THREAD
314 0 : if (PyThread_get_thread_ident() != main_thread) {
315 0 : PyErr_SetString(PyExc_ValueError,
316 : "signal only works in main thread");
317 0 : return NULL;
318 : }
319 : #endif
320 0 : if (sig_num < 1 || sig_num >= NSIG) {
321 0 : PyErr_SetString(PyExc_ValueError,
322 : "signal number out of range");
323 0 : return NULL;
324 : }
325 0 : if (obj == IgnoreHandler)
326 0 : func = SIG_IGN;
327 0 : else if (obj == DefaultHandler)
328 0 : func = SIG_DFL;
329 0 : else if (!PyCallable_Check(obj)) {
330 0 : PyErr_SetString(PyExc_TypeError,
331 : "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
332 0 : return NULL;
333 : }
334 : else
335 0 : func = signal_handler;
336 0 : if (PyOS_setsig(sig_num, func) == SIG_ERR) {
337 0 : PyErr_SetFromErrno(PyExc_OSError);
338 0 : return NULL;
339 : }
340 0 : old_handler = Handlers[sig_num].func;
341 0 : Handlers[sig_num].tripped = 0;
342 0 : Py_INCREF(obj);
343 0 : Handlers[sig_num].func = obj;
344 0 : return old_handler;
345 : }
346 :
347 : PyDoc_STRVAR(signal_doc,
348 : "signal(sig, action) -> action\n\
349 : \n\
350 : Set the action for the given signal. The action can be SIG_DFL,\n\
351 : SIG_IGN, or a callable Python object. The previous action is\n\
352 : returned. See getsignal() for possible return values.\n\
353 : \n\
354 : *** IMPORTANT NOTICE ***\n\
355 : A signal handler function is called with two arguments:\n\
356 : the first is the signal number, the second is the interrupted stack frame.");
357 :
358 :
359 : static PyObject *
360 0 : signal_getsignal(PyObject *self, PyObject *args)
361 : {
362 : int sig_num;
363 : PyObject *old_handler;
364 0 : if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
365 0 : return NULL;
366 0 : if (sig_num < 1 || sig_num >= NSIG) {
367 0 : PyErr_SetString(PyExc_ValueError,
368 : "signal number out of range");
369 0 : return NULL;
370 : }
371 0 : old_handler = Handlers[sig_num].func;
372 0 : Py_INCREF(old_handler);
373 0 : return old_handler;
374 : }
375 :
376 : PyDoc_STRVAR(getsignal_doc,
377 : "getsignal(sig) -> action\n\
378 : \n\
379 : Return the current action for the given signal. The return value can be:\n\
380 : SIG_IGN -- if the signal is being ignored\n\
381 : SIG_DFL -- if the default action for the signal is in effect\n\
382 : None -- if an unknown handler is in effect\n\
383 : anything else -- the callable Python object used as a handler");
384 :
385 : #ifdef HAVE_SIGINTERRUPT
386 : PyDoc_STRVAR(siginterrupt_doc,
387 : "siginterrupt(sig, flag) -> None\n\
388 : change system call restart behaviour: if flag is False, system calls\n\
389 : will be restarted when interrupted by signal sig, else system calls\n\
390 : will be interrupted.");
391 :
392 : static PyObject *
393 0 : signal_siginterrupt(PyObject *self, PyObject *args)
394 : {
395 : int sig_num;
396 : int flag;
397 :
398 0 : if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag))
399 0 : return NULL;
400 0 : if (sig_num < 1 || sig_num >= NSIG) {
401 0 : PyErr_SetString(PyExc_ValueError,
402 : "signal number out of range");
403 0 : return NULL;
404 : }
405 0 : if (siginterrupt(sig_num, flag)<0) {
406 0 : PyErr_SetFromErrno(PyExc_OSError);
407 0 : return NULL;
408 : }
409 :
410 0 : Py_INCREF(Py_None);
411 0 : return Py_None;
412 : }
413 :
414 : #endif
415 :
416 : static PyObject *
417 0 : signal_set_wakeup_fd(PyObject *self, PyObject *args)
418 : {
419 : struct stat buf;
420 : int fd, old_fd;
421 0 : if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd))
422 0 : return NULL;
423 : #ifdef WITH_THREAD
424 0 : if (PyThread_get_thread_ident() != main_thread) {
425 0 : PyErr_SetString(PyExc_ValueError,
426 : "set_wakeup_fd only works in main thread");
427 0 : return NULL;
428 : }
429 : #endif
430 0 : if (fd != -1 && fstat(fd, &buf) != 0) {
431 0 : PyErr_SetString(PyExc_ValueError, "invalid fd");
432 0 : return NULL;
433 : }
434 0 : old_fd = wakeup_fd;
435 0 : wakeup_fd = fd;
436 0 : return PyLong_FromLong(old_fd);
437 : }
438 :
439 : PyDoc_STRVAR(set_wakeup_fd_doc,
440 : "set_wakeup_fd(fd) -> fd\n\
441 : \n\
442 : Sets the fd to be written to (with '\\0') when a signal\n\
443 : comes in. A library can use this to wakeup select or poll.\n\
444 : The previous fd is returned.\n\
445 : \n\
446 : The fd must be non-blocking.");
447 :
448 : /* C API for the same, without all the error checking */
449 : int
450 0 : PySignal_SetWakeupFd(int fd)
451 : {
452 0 : int old_fd = wakeup_fd;
453 0 : if (fd < 0)
454 0 : fd = -1;
455 0 : wakeup_fd = fd;
456 0 : return old_fd;
457 : }
458 :
459 :
460 : #ifdef HAVE_SETITIMER
461 : static PyObject *
462 0 : signal_setitimer(PyObject *self, PyObject *args)
463 : {
464 : double first;
465 0 : double interval = 0;
466 : int which;
467 : struct itimerval new, old;
468 :
469 0 : if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval))
470 0 : return NULL;
471 :
472 0 : timeval_from_double(first, &new.it_value);
473 0 : timeval_from_double(interval, &new.it_interval);
474 : /* Let OS check "which" value */
475 0 : if (setitimer(which, &new, &old) != 0) {
476 0 : PyErr_SetFromErrno(ItimerError);
477 0 : return NULL;
478 : }
479 :
480 0 : return itimer_retval(&old);
481 : }
482 :
483 : PyDoc_STRVAR(setitimer_doc,
484 : "setitimer(which, seconds[, interval])\n\
485 : \n\
486 : Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\
487 : or ITIMER_PROF) to fire after value seconds and after\n\
488 : that every interval seconds.\n\
489 : The itimer can be cleared by setting seconds to zero.\n\
490 : \n\
491 : Returns old values as a tuple: (delay, interval).");
492 : #endif
493 :
494 :
495 : #ifdef HAVE_GETITIMER
496 : static PyObject *
497 0 : signal_getitimer(PyObject *self, PyObject *args)
498 : {
499 : int which;
500 : struct itimerval old;
501 :
502 0 : if (!PyArg_ParseTuple(args, "i:getitimer", &which))
503 0 : return NULL;
504 :
505 0 : if (getitimer(which, &old) != 0) {
506 0 : PyErr_SetFromErrno(ItimerError);
507 0 : return NULL;
508 : }
509 :
510 0 : return itimer_retval(&old);
511 : }
512 :
513 : PyDoc_STRVAR(getitimer_doc,
514 : "getitimer(which)\n\
515 : \n\
516 : Returns current value of given itimer.");
517 : #endif
518 :
519 : #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \
520 : defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
521 : /* Convert an iterable to a sigset.
522 : Return 0 on success, return -1 and raise an exception on error. */
523 :
524 : static int
525 0 : iterable_to_sigset(PyObject *iterable, sigset_t *mask)
526 : {
527 0 : int result = -1;
528 : PyObject *iterator, *item;
529 : long signum;
530 : int err;
531 :
532 0 : sigemptyset(mask);
533 :
534 0 : iterator = PyObject_GetIter(iterable);
535 0 : if (iterator == NULL)
536 0 : goto error;
537 :
538 : while (1)
539 : {
540 0 : item = PyIter_Next(iterator);
541 0 : if (item == NULL) {
542 0 : if (PyErr_Occurred())
543 0 : goto error;
544 : else
545 0 : break;
546 : }
547 :
548 0 : signum = PyLong_AsLong(item);
549 0 : Py_DECREF(item);
550 0 : if (signum == -1 && PyErr_Occurred())
551 0 : goto error;
552 0 : if (0 < signum && signum < NSIG)
553 0 : err = sigaddset(mask, (int)signum);
554 : else
555 0 : err = 1;
556 0 : if (err) {
557 0 : PyErr_Format(PyExc_ValueError,
558 : "signal number %ld out of range", signum);
559 0 : goto error;
560 : }
561 0 : }
562 0 : result = 0;
563 :
564 : error:
565 0 : Py_XDECREF(iterator);
566 0 : return result;
567 : }
568 : #endif
569 :
570 : #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
571 : static PyObject*
572 0 : sigset_to_set(sigset_t mask)
573 : {
574 : PyObject *signum, *result;
575 : int sig;
576 :
577 0 : result = PySet_New(0);
578 0 : if (result == NULL)
579 0 : return NULL;
580 :
581 0 : for (sig = 1; sig < NSIG; sig++) {
582 0 : if (sigismember(&mask, sig) != 1)
583 0 : continue;
584 :
585 : /* Handle the case where it is a member by adding the signal to
586 : the result list. Ignore the other cases because they mean the
587 : signal isn't a member of the mask or the signal was invalid,
588 : and an invalid signal must have been our fault in constructing
589 : the loop boundaries. */
590 0 : signum = PyLong_FromLong(sig);
591 0 : if (signum == NULL) {
592 0 : Py_DECREF(result);
593 0 : return NULL;
594 : }
595 0 : if (PySet_Add(result, signum) == -1) {
596 0 : Py_DECREF(signum);
597 0 : Py_DECREF(result);
598 0 : return NULL;
599 : }
600 0 : Py_DECREF(signum);
601 : }
602 0 : return result;
603 : }
604 : #endif
605 :
606 : #ifdef PYPTHREAD_SIGMASK
607 : static PyObject *
608 0 : signal_pthread_sigmask(PyObject *self, PyObject *args)
609 : {
610 : int how;
611 : PyObject *signals;
612 : sigset_t mask, previous;
613 : int err;
614 :
615 0 : if (!PyArg_ParseTuple(args, "iO:pthread_sigmask", &how, &signals))
616 0 : return NULL;
617 :
618 0 : if (iterable_to_sigset(signals, &mask))
619 0 : return NULL;
620 :
621 0 : err = pthread_sigmask(how, &mask, &previous);
622 0 : if (err != 0) {
623 0 : errno = err;
624 0 : PyErr_SetFromErrno(PyExc_OSError);
625 0 : return NULL;
626 : }
627 :
628 : /* if signals was unblocked, signal handlers have been called */
629 0 : if (PyErr_CheckSignals())
630 0 : return NULL;
631 :
632 0 : return sigset_to_set(previous);
633 : }
634 :
635 : PyDoc_STRVAR(signal_pthread_sigmask_doc,
636 : "pthread_sigmask(how, mask) -> old mask\n\
637 : \n\
638 : Fetch and/or change the signal mask of the calling thread.");
639 : #endif /* #ifdef PYPTHREAD_SIGMASK */
640 :
641 :
642 : #ifdef HAVE_SIGPENDING
643 : static PyObject *
644 0 : signal_sigpending(PyObject *self)
645 : {
646 : int err;
647 : sigset_t mask;
648 0 : err = sigpending(&mask);
649 0 : if (err)
650 0 : return PyErr_SetFromErrno(PyExc_OSError);
651 0 : return sigset_to_set(mask);
652 : }
653 :
654 : PyDoc_STRVAR(signal_sigpending_doc,
655 : "sigpending() -> list\n\
656 : \n\
657 : Examine pending signals.");
658 : #endif /* #ifdef HAVE_SIGPENDING */
659 :
660 :
661 : #ifdef HAVE_SIGWAIT
662 : static PyObject *
663 0 : signal_sigwait(PyObject *self, PyObject *args)
664 : {
665 : PyObject *signals;
666 : sigset_t set;
667 : int err, signum;
668 :
669 0 : if (!PyArg_ParseTuple(args, "O:sigwait", &signals))
670 0 : return NULL;
671 :
672 0 : if (iterable_to_sigset(signals, &set))
673 0 : return NULL;
674 :
675 0 : Py_BEGIN_ALLOW_THREADS
676 0 : err = sigwait(&set, &signum);
677 0 : Py_END_ALLOW_THREADS
678 0 : if (err) {
679 0 : errno = err;
680 0 : return PyErr_SetFromErrno(PyExc_OSError);
681 : }
682 :
683 0 : return PyLong_FromLong(signum);
684 : }
685 :
686 : PyDoc_STRVAR(signal_sigwait_doc,
687 : "sigwait(sigset) -> signum\n\
688 : \n\
689 : Wait a signal.");
690 : #endif /* #ifdef HAVE_SIGPENDING */
691 :
692 : #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
693 : static int initialized;
694 : static PyStructSequence_Field struct_siginfo_fields[] = {
695 : {"si_signo", "signal number"},
696 : {"si_code", "signal code"},
697 : {"si_errno", "errno associated with this signal"},
698 : {"si_pid", "sending process ID"},
699 : {"si_uid", "real user ID of sending process"},
700 : {"si_status", "exit value or signal"},
701 : {"si_band", "band event for SIGPOLL"},
702 : {0}
703 : };
704 :
705 : PyDoc_STRVAR(struct_siginfo__doc__,
706 : "struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\
707 : This object may be accessed either as a tuple of\n\
708 : (si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\
709 : or via the attributes si_signo, si_code, and so on.");
710 :
711 : static PyStructSequence_Desc struct_siginfo_desc = {
712 : "signal.struct_siginfo", /* name */
713 : struct_siginfo__doc__, /* doc */
714 : struct_siginfo_fields, /* fields */
715 : 7 /* n_in_sequence */
716 : };
717 :
718 : static PyTypeObject SiginfoType;
719 :
720 : static PyObject *
721 0 : fill_siginfo(siginfo_t *si)
722 : {
723 0 : PyObject *result = PyStructSequence_New(&SiginfoType);
724 0 : if (!result)
725 0 : return NULL;
726 :
727 0 : PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo)));
728 0 : PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code)));
729 0 : PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno)));
730 0 : PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid));
731 0 : PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si->si_uid)));
732 0 : PyStructSequence_SET_ITEM(result, 5,
733 : PyLong_FromLong((long)(si->si_status)));
734 0 : PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));
735 0 : if (PyErr_Occurred()) {
736 0 : Py_DECREF(result);
737 0 : return NULL;
738 : }
739 :
740 0 : return result;
741 : }
742 : #endif
743 :
744 : #ifdef HAVE_SIGWAITINFO
745 : static PyObject *
746 0 : signal_sigwaitinfo(PyObject *self, PyObject *args)
747 : {
748 : PyObject *signals;
749 : sigset_t set;
750 : siginfo_t si;
751 : int err;
752 :
753 0 : if (!PyArg_ParseTuple(args, "O:sigwaitinfo", &signals))
754 0 : return NULL;
755 :
756 0 : if (iterable_to_sigset(signals, &set))
757 0 : return NULL;
758 :
759 0 : Py_BEGIN_ALLOW_THREADS
760 0 : err = sigwaitinfo(&set, &si);
761 0 : Py_END_ALLOW_THREADS
762 0 : if (err == -1)
763 0 : return PyErr_SetFromErrno(PyExc_OSError);
764 :
765 0 : return fill_siginfo(&si);
766 : }
767 :
768 : PyDoc_STRVAR(signal_sigwaitinfo_doc,
769 : "sigwaitinfo(sigset) -> struct_siginfo\n\
770 : \n\
771 : Wait synchronously for a signal until one of the signals in *sigset* is\n\
772 : delivered.\n\
773 : Returns a struct_siginfo containing information about the signal.");
774 : #endif /* #ifdef HAVE_SIGWAITINFO */
775 :
776 : #ifdef HAVE_SIGTIMEDWAIT
777 : static PyObject *
778 0 : signal_sigtimedwait(PyObject *self, PyObject *args)
779 : {
780 : PyObject *signals, *timeout;
781 : struct timespec buf;
782 : sigset_t set;
783 : siginfo_t si;
784 : int err;
785 :
786 0 : if (!PyArg_ParseTuple(args, "OO:sigtimedwait",
787 : &signals, &timeout))
788 0 : return NULL;
789 :
790 0 : if (_PyTime_ObjectToTimespec(timeout, &buf.tv_sec, &buf.tv_nsec) == -1)
791 0 : return NULL;
792 :
793 0 : if (buf.tv_sec < 0 || buf.tv_nsec < 0) {
794 0 : PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
795 0 : return NULL;
796 : }
797 :
798 0 : if (iterable_to_sigset(signals, &set))
799 0 : return NULL;
800 :
801 0 : Py_BEGIN_ALLOW_THREADS
802 0 : err = sigtimedwait(&set, &si, &buf);
803 0 : Py_END_ALLOW_THREADS
804 0 : if (err == -1) {
805 0 : if (errno == EAGAIN)
806 0 : Py_RETURN_NONE;
807 : else
808 0 : return PyErr_SetFromErrno(PyExc_OSError);
809 : }
810 :
811 0 : return fill_siginfo(&si);
812 : }
813 :
814 : PyDoc_STRVAR(signal_sigtimedwait_doc,
815 : "sigtimedwait(sigset, (timeout_sec, timeout_nsec)) -> struct_siginfo\n\
816 : \n\
817 : Like sigwaitinfo(), but with a timeout specified as a tuple of (seconds,\n\
818 : nanoseconds).");
819 : #endif /* #ifdef HAVE_SIGTIMEDWAIT */
820 :
821 :
822 : #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)
823 : static PyObject *
824 0 : signal_pthread_kill(PyObject *self, PyObject *args)
825 : {
826 : long tid;
827 : int signum;
828 : int err;
829 :
830 0 : if (!PyArg_ParseTuple(args, "li:pthread_kill", &tid, &signum))
831 0 : return NULL;
832 :
833 0 : err = pthread_kill((pthread_t)tid, signum);
834 0 : if (err != 0) {
835 0 : errno = err;
836 0 : PyErr_SetFromErrno(PyExc_OSError);
837 0 : return NULL;
838 : }
839 :
840 : /* the signal may have been send to the current thread */
841 0 : if (PyErr_CheckSignals())
842 0 : return NULL;
843 :
844 0 : Py_RETURN_NONE;
845 : }
846 :
847 : PyDoc_STRVAR(signal_pthread_kill_doc,
848 : "pthread_kill(thread_id, signum)\n\
849 : \n\
850 : Send a signal to a thread.");
851 : #endif /* #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) */
852 :
853 :
854 :
855 : /* List of functions defined in the module */
856 : static PyMethodDef signal_methods[] = {
857 : #ifdef HAVE_ALARM
858 : {"alarm", signal_alarm, METH_VARARGS, alarm_doc},
859 : #endif
860 : #ifdef HAVE_SETITIMER
861 : {"setitimer", signal_setitimer, METH_VARARGS, setitimer_doc},
862 : #endif
863 : #ifdef HAVE_GETITIMER
864 : {"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc},
865 : #endif
866 : {"signal", signal_signal, METH_VARARGS, signal_doc},
867 : {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc},
868 : {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc},
869 : #ifdef HAVE_SIGINTERRUPT
870 : {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc},
871 : #endif
872 : #ifdef HAVE_PAUSE
873 : {"pause", (PyCFunction)signal_pause,
874 : METH_NOARGS, pause_doc},
875 : #endif
876 : {"default_int_handler", signal_default_int_handler,
877 : METH_VARARGS, default_int_handler_doc},
878 : #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)
879 : {"pthread_kill", (PyCFunction)signal_pthread_kill,
880 : METH_VARARGS, signal_pthread_kill_doc},
881 : #endif
882 : #ifdef PYPTHREAD_SIGMASK
883 : {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask,
884 : METH_VARARGS, signal_pthread_sigmask_doc},
885 : #endif
886 : #ifdef HAVE_SIGPENDING
887 : {"sigpending", (PyCFunction)signal_sigpending,
888 : METH_NOARGS, signal_sigpending_doc},
889 : #endif
890 : #ifdef HAVE_SIGWAIT
891 : {"sigwait", (PyCFunction)signal_sigwait,
892 : METH_VARARGS, signal_sigwait_doc},
893 : #endif
894 : #ifdef HAVE_SIGWAITINFO
895 : {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo,
896 : METH_VARARGS, signal_sigwaitinfo_doc},
897 : #endif
898 : #ifdef HAVE_SIGTIMEDWAIT
899 : {"sigtimedwait", (PyCFunction)signal_sigtimedwait,
900 : METH_VARARGS, signal_sigtimedwait_doc},
901 : #endif
902 : {NULL, NULL} /* sentinel */
903 : };
904 :
905 :
906 : PyDoc_STRVAR(module_doc,
907 : "This module provides mechanisms to use signal handlers in Python.\n\
908 : \n\
909 : Functions:\n\
910 : \n\
911 : alarm() -- cause SIGALRM after a specified time [Unix only]\n\
912 : setitimer() -- cause a signal (described below) after a specified\n\
913 : float time and the timer may restart then [Unix only]\n\
914 : getitimer() -- get current value of timer [Unix only]\n\
915 : signal() -- set the action for a given signal\n\
916 : getsignal() -- get the signal action for a given signal\n\
917 : pause() -- wait until a signal arrives [Unix only]\n\
918 : default_int_handler() -- default SIGINT handler\n\
919 : \n\
920 : signal constants:\n\
921 : SIG_DFL -- used to refer to the system default handler\n\
922 : SIG_IGN -- used to ignore the signal\n\
923 : NSIG -- number of defined signals\n\
924 : SIGINT, SIGTERM, etc. -- signal numbers\n\
925 : \n\
926 : itimer constants:\n\
927 : ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
928 : expiration\n\
929 : ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
930 : and delivers SIGVTALRM upon expiration\n\
931 : ITIMER_PROF -- decrements both when the process is executing and\n\
932 : when the system is executing on behalf of the process.\n\
933 : Coupled with ITIMER_VIRTUAL, this timer is usually\n\
934 : used to profile the time spent by the application\n\
935 : in user and kernel space. SIGPROF is delivered upon\n\
936 : expiration.\n\
937 : \n\n\
938 : *** IMPORTANT NOTICE ***\n\
939 : A signal handler function is called with two arguments:\n\
940 : the first is the signal number, the second is the interrupted stack frame.");
941 :
942 : static struct PyModuleDef signalmodule = {
943 : PyModuleDef_HEAD_INIT,
944 : "signal",
945 : module_doc,
946 : -1,
947 : signal_methods,
948 : NULL,
949 : NULL,
950 : NULL,
951 : NULL
952 : };
953 :
954 : PyMODINIT_FUNC
955 1 : PyInit_signal(void)
956 : {
957 : PyObject *m, *d, *x;
958 : int i;
959 :
960 : #ifdef WITH_THREAD
961 1 : main_thread = PyThread_get_thread_ident();
962 1 : main_pid = getpid();
963 : #endif
964 :
965 : /* Create the module and add the functions */
966 1 : m = PyModule_Create(&signalmodule);
967 1 : if (m == NULL)
968 0 : return NULL;
969 :
970 : #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
971 1 : if (!initialized)
972 1 : PyStructSequence_InitType(&SiginfoType, &struct_siginfo_desc);
973 :
974 1 : Py_INCREF((PyObject*) &SiginfoType);
975 1 : PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType);
976 1 : initialized = 1;
977 : #endif
978 :
979 : /* Add some symbolic constants to the module */
980 1 : d = PyModule_GetDict(m);
981 :
982 1 : x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
983 1 : if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
984 : goto finally;
985 :
986 1 : x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
987 1 : if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
988 : goto finally;
989 :
990 1 : x = PyLong_FromLong((long)NSIG);
991 1 : if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
992 : goto finally;
993 1 : Py_DECREF(x);
994 :
995 : #ifdef SIG_BLOCK
996 1 : if (PyModule_AddIntMacro(m, SIG_BLOCK))
997 0 : goto finally;
998 : #endif
999 : #ifdef SIG_UNBLOCK
1000 1 : if (PyModule_AddIntMacro(m, SIG_UNBLOCK))
1001 0 : goto finally;
1002 : #endif
1003 : #ifdef SIG_SETMASK
1004 1 : if (PyModule_AddIntMacro(m, SIG_SETMASK))
1005 0 : goto finally;
1006 : #endif
1007 :
1008 1 : x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
1009 1 : if (!x)
1010 0 : goto finally;
1011 1 : Py_INCREF(IntHandler);
1012 :
1013 1 : Handlers[0].tripped = 0;
1014 65 : for (i = 1; i < NSIG; i++) {
1015 : void (*t)(int);
1016 64 : t = PyOS_getsig(i);
1017 64 : Handlers[i].tripped = 0;
1018 64 : if (t == SIG_DFL)
1019 50 : Handlers[i].func = DefaultHandler;
1020 14 : else if (t == SIG_IGN)
1021 3 : Handlers[i].func = IgnoreHandler;
1022 : else
1023 11 : Handlers[i].func = Py_None; /* None of our business */
1024 64 : Py_INCREF(Handlers[i].func);
1025 : }
1026 1 : if (Handlers[SIGINT].func == DefaultHandler) {
1027 : /* Install default int handler */
1028 0 : Py_INCREF(IntHandler);
1029 0 : Py_DECREF(Handlers[SIGINT].func);
1030 0 : Handlers[SIGINT].func = IntHandler;
1031 0 : old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
1032 : }
1033 :
1034 : #ifdef SIGHUP
1035 1 : x = PyLong_FromLong(SIGHUP);
1036 1 : PyDict_SetItemString(d, "SIGHUP", x);
1037 1 : Py_XDECREF(x);
1038 : #endif
1039 : #ifdef SIGINT
1040 1 : x = PyLong_FromLong(SIGINT);
1041 1 : PyDict_SetItemString(d, "SIGINT", x);
1042 1 : Py_XDECREF(x);
1043 : #endif
1044 : #ifdef SIGBREAK
1045 : x = PyLong_FromLong(SIGBREAK);
1046 : PyDict_SetItemString(d, "SIGBREAK", x);
1047 : Py_XDECREF(x);
1048 : #endif
1049 : #ifdef SIGQUIT
1050 1 : x = PyLong_FromLong(SIGQUIT);
1051 1 : PyDict_SetItemString(d, "SIGQUIT", x);
1052 1 : Py_XDECREF(x);
1053 : #endif
1054 : #ifdef SIGILL
1055 1 : x = PyLong_FromLong(SIGILL);
1056 1 : PyDict_SetItemString(d, "SIGILL", x);
1057 1 : Py_XDECREF(x);
1058 : #endif
1059 : #ifdef SIGTRAP
1060 1 : x = PyLong_FromLong(SIGTRAP);
1061 1 : PyDict_SetItemString(d, "SIGTRAP", x);
1062 1 : Py_XDECREF(x);
1063 : #endif
1064 : #ifdef SIGIOT
1065 1 : x = PyLong_FromLong(SIGIOT);
1066 1 : PyDict_SetItemString(d, "SIGIOT", x);
1067 1 : Py_XDECREF(x);
1068 : #endif
1069 : #ifdef SIGABRT
1070 1 : x = PyLong_FromLong(SIGABRT);
1071 1 : PyDict_SetItemString(d, "SIGABRT", x);
1072 1 : Py_XDECREF(x);
1073 : #endif
1074 : #ifdef SIGEMT
1075 : x = PyLong_FromLong(SIGEMT);
1076 : PyDict_SetItemString(d, "SIGEMT", x);
1077 : Py_XDECREF(x);
1078 : #endif
1079 : #ifdef SIGFPE
1080 1 : x = PyLong_FromLong(SIGFPE);
1081 1 : PyDict_SetItemString(d, "SIGFPE", x);
1082 1 : Py_XDECREF(x);
1083 : #endif
1084 : #ifdef SIGKILL
1085 1 : x = PyLong_FromLong(SIGKILL);
1086 1 : PyDict_SetItemString(d, "SIGKILL", x);
1087 1 : Py_XDECREF(x);
1088 : #endif
1089 : #ifdef SIGBUS
1090 1 : x = PyLong_FromLong(SIGBUS);
1091 1 : PyDict_SetItemString(d, "SIGBUS", x);
1092 1 : Py_XDECREF(x);
1093 : #endif
1094 : #ifdef SIGSEGV
1095 1 : x = PyLong_FromLong(SIGSEGV);
1096 1 : PyDict_SetItemString(d, "SIGSEGV", x);
1097 1 : Py_XDECREF(x);
1098 : #endif
1099 : #ifdef SIGSYS
1100 1 : x = PyLong_FromLong(SIGSYS);
1101 1 : PyDict_SetItemString(d, "SIGSYS", x);
1102 1 : Py_XDECREF(x);
1103 : #endif
1104 : #ifdef SIGPIPE
1105 1 : x = PyLong_FromLong(SIGPIPE);
1106 1 : PyDict_SetItemString(d, "SIGPIPE", x);
1107 1 : Py_XDECREF(x);
1108 : #endif
1109 : #ifdef SIGALRM
1110 1 : x = PyLong_FromLong(SIGALRM);
1111 1 : PyDict_SetItemString(d, "SIGALRM", x);
1112 1 : Py_XDECREF(x);
1113 : #endif
1114 : #ifdef SIGTERM
1115 1 : x = PyLong_FromLong(SIGTERM);
1116 1 : PyDict_SetItemString(d, "SIGTERM", x);
1117 1 : Py_XDECREF(x);
1118 : #endif
1119 : #ifdef SIGUSR1
1120 1 : x = PyLong_FromLong(SIGUSR1);
1121 1 : PyDict_SetItemString(d, "SIGUSR1", x);
1122 1 : Py_XDECREF(x);
1123 : #endif
1124 : #ifdef SIGUSR2
1125 1 : x = PyLong_FromLong(SIGUSR2);
1126 1 : PyDict_SetItemString(d, "SIGUSR2", x);
1127 1 : Py_XDECREF(x);
1128 : #endif
1129 : #ifdef SIGCLD
1130 1 : x = PyLong_FromLong(SIGCLD);
1131 1 : PyDict_SetItemString(d, "SIGCLD", x);
1132 1 : Py_XDECREF(x);
1133 : #endif
1134 : #ifdef SIGCHLD
1135 1 : x = PyLong_FromLong(SIGCHLD);
1136 1 : PyDict_SetItemString(d, "SIGCHLD", x);
1137 1 : Py_XDECREF(x);
1138 : #endif
1139 : #ifdef SIGPWR
1140 1 : x = PyLong_FromLong(SIGPWR);
1141 1 : PyDict_SetItemString(d, "SIGPWR", x);
1142 1 : Py_XDECREF(x);
1143 : #endif
1144 : #ifdef SIGIO
1145 1 : x = PyLong_FromLong(SIGIO);
1146 1 : PyDict_SetItemString(d, "SIGIO", x);
1147 1 : Py_XDECREF(x);
1148 : #endif
1149 : #ifdef SIGURG
1150 1 : x = PyLong_FromLong(SIGURG);
1151 1 : PyDict_SetItemString(d, "SIGURG", x);
1152 1 : Py_XDECREF(x);
1153 : #endif
1154 : #ifdef SIGWINCH
1155 1 : x = PyLong_FromLong(SIGWINCH);
1156 1 : PyDict_SetItemString(d, "SIGWINCH", x);
1157 1 : Py_XDECREF(x);
1158 : #endif
1159 : #ifdef SIGPOLL
1160 1 : x = PyLong_FromLong(SIGPOLL);
1161 1 : PyDict_SetItemString(d, "SIGPOLL", x);
1162 1 : Py_XDECREF(x);
1163 : #endif
1164 : #ifdef SIGSTOP
1165 1 : x = PyLong_FromLong(SIGSTOP);
1166 1 : PyDict_SetItemString(d, "SIGSTOP", x);
1167 1 : Py_XDECREF(x);
1168 : #endif
1169 : #ifdef SIGTSTP
1170 1 : x = PyLong_FromLong(SIGTSTP);
1171 1 : PyDict_SetItemString(d, "SIGTSTP", x);
1172 1 : Py_XDECREF(x);
1173 : #endif
1174 : #ifdef SIGCONT
1175 1 : x = PyLong_FromLong(SIGCONT);
1176 1 : PyDict_SetItemString(d, "SIGCONT", x);
1177 1 : Py_XDECREF(x);
1178 : #endif
1179 : #ifdef SIGTTIN
1180 1 : x = PyLong_FromLong(SIGTTIN);
1181 1 : PyDict_SetItemString(d, "SIGTTIN", x);
1182 1 : Py_XDECREF(x);
1183 : #endif
1184 : #ifdef SIGTTOU
1185 1 : x = PyLong_FromLong(SIGTTOU);
1186 1 : PyDict_SetItemString(d, "SIGTTOU", x);
1187 1 : Py_XDECREF(x);
1188 : #endif
1189 : #ifdef SIGVTALRM
1190 1 : x = PyLong_FromLong(SIGVTALRM);
1191 1 : PyDict_SetItemString(d, "SIGVTALRM", x);
1192 1 : Py_XDECREF(x);
1193 : #endif
1194 : #ifdef SIGPROF
1195 1 : x = PyLong_FromLong(SIGPROF);
1196 1 : PyDict_SetItemString(d, "SIGPROF", x);
1197 1 : Py_XDECREF(x);
1198 : #endif
1199 : #ifdef SIGXCPU
1200 1 : x = PyLong_FromLong(SIGXCPU);
1201 1 : PyDict_SetItemString(d, "SIGXCPU", x);
1202 1 : Py_XDECREF(x);
1203 : #endif
1204 : #ifdef SIGXFSZ
1205 1 : x = PyLong_FromLong(SIGXFSZ);
1206 1 : PyDict_SetItemString(d, "SIGXFSZ", x);
1207 1 : Py_XDECREF(x);
1208 : #endif
1209 : #ifdef SIGRTMIN
1210 1 : x = PyLong_FromLong(SIGRTMIN);
1211 1 : PyDict_SetItemString(d, "SIGRTMIN", x);
1212 1 : Py_XDECREF(x);
1213 : #endif
1214 : #ifdef SIGRTMAX
1215 1 : x = PyLong_FromLong(SIGRTMAX);
1216 1 : PyDict_SetItemString(d, "SIGRTMAX", x);
1217 1 : Py_XDECREF(x);
1218 : #endif
1219 : #ifdef SIGINFO
1220 : x = PyLong_FromLong(SIGINFO);
1221 : PyDict_SetItemString(d, "SIGINFO", x);
1222 : Py_XDECREF(x);
1223 : #endif
1224 :
1225 : #ifdef ITIMER_REAL
1226 1 : x = PyLong_FromLong(ITIMER_REAL);
1227 1 : PyDict_SetItemString(d, "ITIMER_REAL", x);
1228 1 : Py_DECREF(x);
1229 : #endif
1230 : #ifdef ITIMER_VIRTUAL
1231 1 : x = PyLong_FromLong(ITIMER_VIRTUAL);
1232 1 : PyDict_SetItemString(d, "ITIMER_VIRTUAL", x);
1233 1 : Py_DECREF(x);
1234 : #endif
1235 : #ifdef ITIMER_PROF
1236 1 : x = PyLong_FromLong(ITIMER_PROF);
1237 1 : PyDict_SetItemString(d, "ITIMER_PROF", x);
1238 1 : Py_DECREF(x);
1239 : #endif
1240 :
1241 : #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
1242 1 : ItimerError = PyErr_NewException("signal.ItimerError",
1243 : PyExc_IOError, NULL);
1244 1 : if (ItimerError != NULL)
1245 1 : PyDict_SetItemString(d, "ItimerError", ItimerError);
1246 : #endif
1247 :
1248 : #ifdef CTRL_C_EVENT
1249 : x = PyLong_FromLong(CTRL_C_EVENT);
1250 : PyDict_SetItemString(d, "CTRL_C_EVENT", x);
1251 : Py_DECREF(x);
1252 : #endif
1253 :
1254 : #ifdef CTRL_BREAK_EVENT
1255 : x = PyLong_FromLong(CTRL_BREAK_EVENT);
1256 : PyDict_SetItemString(d, "CTRL_BREAK_EVENT", x);
1257 : Py_DECREF(x);
1258 : #endif
1259 :
1260 : #ifdef MS_WINDOWS
1261 : /* Create manual-reset event, initially unset */
1262 : sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE);
1263 : #endif
1264 :
1265 1 : if (PyErr_Occurred()) {
1266 0 : Py_DECREF(m);
1267 0 : m = NULL;
1268 : }
1269 :
1270 : finally:
1271 1 : return m;
1272 : }
1273 :
1274 : static void
1275 0 : finisignal(void)
1276 : {
1277 : int i;
1278 : PyObject *func;
1279 :
1280 0 : PyOS_setsig(SIGINT, old_siginthandler);
1281 0 : old_siginthandler = SIG_DFL;
1282 :
1283 0 : for (i = 1; i < NSIG; i++) {
1284 0 : func = Handlers[i].func;
1285 0 : Handlers[i].tripped = 0;
1286 0 : Handlers[i].func = NULL;
1287 0 : if (i != SIGINT && func != NULL && func != Py_None &&
1288 0 : func != DefaultHandler && func != IgnoreHandler)
1289 0 : PyOS_setsig(i, SIG_DFL);
1290 0 : Py_XDECREF(func);
1291 : }
1292 :
1293 0 : Py_XDECREF(IntHandler);
1294 0 : IntHandler = NULL;
1295 0 : Py_XDECREF(DefaultHandler);
1296 0 : DefaultHandler = NULL;
1297 0 : Py_XDECREF(IgnoreHandler);
1298 0 : IgnoreHandler = NULL;
1299 0 : }
1300 :
1301 :
1302 : /* Declared in pyerrors.h */
1303 : int
1304 4046 : PyErr_CheckSignals(void)
1305 : {
1306 : int i;
1307 : PyObject *f;
1308 :
1309 4046 : if (!is_tripped)
1310 4046 : return 0;
1311 :
1312 : #ifdef WITH_THREAD
1313 0 : if (PyThread_get_thread_ident() != main_thread)
1314 0 : return 0;
1315 : #endif
1316 :
1317 : /*
1318 : * The is_tripped variable is meant to speed up the calls to
1319 : * PyErr_CheckSignals (both directly or via pending calls) when no
1320 : * signal has arrived. This variable is set to 1 when a signal arrives
1321 : * and it is set to 0 here, when we know some signals arrived. This way
1322 : * we can run the registered handlers with no signals blocked.
1323 : *
1324 : * NOTE: with this approach we can have a situation where is_tripped is
1325 : * 1 but we have no more signals to handle (Handlers[i].tripped
1326 : * is 0 for every signal i). This won't do us any harm (except
1327 : * we're gonna spent some cycles for nothing). This happens when
1328 : * we receive a signal i after we zero is_tripped and before we
1329 : * check Handlers[i].tripped.
1330 : */
1331 0 : is_tripped = 0;
1332 :
1333 0 : if (!(f = (PyObject *)PyEval_GetFrame()))
1334 0 : f = Py_None;
1335 :
1336 0 : for (i = 1; i < NSIG; i++) {
1337 0 : if (Handlers[i].tripped) {
1338 0 : PyObject *result = NULL;
1339 0 : PyObject *arglist = Py_BuildValue("(iO)", i, f);
1340 0 : Handlers[i].tripped = 0;
1341 :
1342 0 : if (arglist) {
1343 0 : result = PyEval_CallObject(Handlers[i].func,
1344 : arglist);
1345 0 : Py_DECREF(arglist);
1346 : }
1347 0 : if (!result)
1348 0 : return -1;
1349 :
1350 0 : Py_DECREF(result);
1351 : }
1352 : }
1353 :
1354 0 : return 0;
1355 : }
1356 :
1357 :
1358 : /* Replacements for intrcheck.c functionality
1359 : * Declared in pyerrors.h
1360 : */
1361 : void
1362 0 : PyErr_SetInterrupt(void)
1363 : {
1364 0 : trip_signal(SIGINT);
1365 0 : }
1366 :
1367 : void
1368 1 : PyOS_InitInterrupts(void)
1369 : {
1370 1 : PyObject *m = PyInit_signal();
1371 1 : if (m) {
1372 1 : _PyImport_FixupBuiltin(m, "signal");
1373 1 : Py_DECREF(m);
1374 : }
1375 1 : }
1376 :
1377 : void
1378 0 : PyOS_FiniInterrupts(void)
1379 : {
1380 0 : finisignal();
1381 0 : }
1382 :
1383 : int
1384 0 : PyOS_InterruptOccurred(void)
1385 : {
1386 0 : if (Handlers[SIGINT].tripped) {
1387 : #ifdef WITH_THREAD
1388 0 : if (PyThread_get_thread_ident() != main_thread)
1389 0 : return 0;
1390 : #endif
1391 0 : Handlers[SIGINT].tripped = 0;
1392 0 : return 1;
1393 : }
1394 0 : return 0;
1395 : }
1396 :
1397 : void
1398 0 : PyOS_AfterFork(void)
1399 : {
1400 : #ifdef WITH_THREAD
1401 : /* PyThread_ReInitTLS() must be called early, to make sure that the TLS API
1402 : * can be called safely. */
1403 0 : PyThread_ReInitTLS();
1404 0 : _PyGILState_Reinit();
1405 0 : PyEval_ReInitThreads();
1406 0 : main_thread = PyThread_get_thread_ident();
1407 0 : main_pid = getpid();
1408 0 : _PyImport_ReInitLock();
1409 : #endif
1410 0 : }
1411 :
1412 : int
1413 0 : _PyOS_IsMainThread(void)
1414 : {
1415 : #ifdef WITH_THREAD
1416 0 : return PyThread_get_thread_ident() == main_thread;
1417 : #else
1418 : return 1;
1419 : #endif
1420 : }
1421 :
1422 : #ifdef MS_WINDOWS
1423 : void *_PyOS_SigintEvent(void)
1424 : {
1425 : /* Returns a manual-reset event which gets tripped whenever
1426 : SIGINT is received.
1427 :
1428 : Python.h does not include windows.h so we do cannot use HANDLE
1429 : as the return type of this function. We use void* instead. */
1430 : return sigint_event;
1431 : }
1432 : #endif
|