[Python-bugs-list] signal()/sigaction() [signalmodule.c] (PR#422)

jan@cendio.se jan@cendio.se
Mon, 31 Jul 2000 14:06:26 -0400 (EDT)


Full_Name: Jan Danielsson
Version: Python-1.6a2
OS: Linux RedHat6.0 Kernel 2.2.5
Submission from: skorpan.cendio.se (193.180.23.65)


Some calls to siginterrupt() are missing somewhere in the
file signalmodule.c and this makes the initial interrupt
character not interrupt the read system call.

Example:

% ./python
Python 1.6a2 (#1, Jul 31 2000, 17:28:30)  [GCC egcs-2.91.66 19990314/Linux
(egcs-1.1.2 release)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> 

At this point: enter your keyboard interrupt character (^C), nothing
happens.  Hit return and the following is written:

Traceback (most recent call last):
  File "<stdin>", line 0, in ?
KeyboardInterrupt
>>> 

If the keyboard interrupt character is typed once again the responce
is immediate:

KeyboardInterrupt
>>>

Maybe the following patch or part of it could be useful to fix
the problem?

--- Python-1.6a2/Modules/signalmodule.c Mon Dec 21 20:32:39 1998
+++ Python-1.6a2.patched/Modules/signalmodule.c Mon Jul 31 19:54:31 2000
@@ -113,6 +113,35 @@
 
 
 ^L
+#ifdef HAVE_SIGACTION
+static RETSIGTYPE * my_signal(int signum, RETSIGTYPE(* handler)())
+{
+       struct sigaction act;
+       struct sigaction old_act;
+       memset(&act, 0, sizeof(act));
+       memset(&old_act, 0, sizeof(old_act));
+       act.sa_handler = handler;
+       if (sigaction(signum, &act, &old_act) == -1) {
+               return SIG_ERR;
+       }
+       return old_act.sa_handler;
+}
+#else
+#ifdef HAVE_SIGINTERRUPT
+static RETSIGTYPE * my_signal(int sig_num, RETSIGTYPE(* handler)())
+{
+       RETSIGTYPE * old_handler;
+       siginterrupt(sig_num, 1);
+       old_handler = signal(sig_num, handler);
+       return old_handler;
+}
+#else
+#define my_signal signal
+#endif
+#endif
+
+
+
 static PyObject *
 signal_default_int_handler(self, arg)
        PyObject *self;
@@ -153,10 +182,7 @@
                return;
        }
 #endif
-#ifdef HAVE_SIGINTERRUPT
-       siginterrupt(sig_num, 1);
-#endif
-       (void)signal(sig_num, &signal_handler);
+       (void)my_signal(sig_num, &signal_handler);
 }
 
 
@@ -243,10 +269,7 @@
        }
        else
                func = signal_handler;
-#ifdef HAVE_SIGINTERRUPT
-       siginterrupt(sig_num, 1);
-#endif
-       if (signal(sig_num, func) == SIG_ERR) {
+       if (my_signal(sig_num, func) == SIG_ERR) {
                PyErr_SetFromErrno(PyExc_RuntimeError);
                return NULL;
        }
@@ -399,7 +422,7 @@
                Py_INCREF(IntHandler);
                Py_DECREF(Handlers[SIGINT].func);
                Handlers[SIGINT].func = IntHandler;
-               old_siginthandler = signal(SIGINT, &signal_handler);
+               old_siginthandler = my_signal(SIGINT, &signal_handler);
        }
 
 #ifdef SIGHUP
@@ -586,7 +609,7 @@
        int i;
        PyObject *func;
 
-       signal(SIGINT, old_siginthandler);
+       my_signal(SIGINT, old_siginthandler);
        old_siginthandler = SIG_DFL;
 
        for (i = 1; i < NSIG; i++) {
@@ -595,7 +618,7 @@
                Handlers[i].func = NULL;
                if (i != SIGINT && func != NULL && func != Py_None &&
                    func != DefaultHandler && func != IgnoreHandler)
-                       signal(i, SIG_DFL);
+                       my_signal(i, SIG_DFL);
                Py_XDECREF(func);
        }