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