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