[Python-bugs-list] bug (Incorrect signal processing) - Python 1.5.2 (PR#102)
Wed, 13 Oct 1999 08:57:09 -0400 (EDT)
> JH> ...... I'm not sure that the
> JH> behavior you're seeing is a bug; it is the behavior I would expect.
> JH> Slow system calls are interrupted, returning EINTR, when a signal
> JH> occurs.
> I'am sure that this behavior is bug becouse:
When I first thought about this, I agreed with Vladimir. If you look
careful at his code, readline() is returning "" when the alarm goes
off; this can't be right, because it's not an end of file. It should
either raise an exception (EINTR) or return one line of valid data.
On the other hand, whatever solution is chosen should be careful that
other signals raise exceptions; in particular you want SIGINT (^C) to
be translated to a KeyboardError exception. Since the C code in
readline() can't tell which signal was trapped or whether the handler
raised an exception, it has two choices, both of which are bad:
- Raise an IOError exception, honoring the EINTR. Unfortunately, in
the SIGINT/^C case, the handler will run after this exception is
raised, and it will raise KeyboardError. The Python program will
*probably* see the KeyboardError exception, but it is not guaranteed
that the signal handler is run immediately. (The Python-level signal
handler is run only after the Python virtual machine finishes the
current instruction, i.e. after the readline() completes.)
- Continue to read a line, ignoring the EINTR. Unfortunately, this
would mean that the user has to type ^C followed by Return to
interrupt the program!
An alternative solution would be to arrange for the Python-level
interrupt handler to execute inside the readline() method, and to
restart the read only when it raises no exception; but this would
require a massive code rewrite (you'd want this behavior in any place
that does a blocking I/O operation).
Concluding, I think Vladimir is better off not to use signal handlers
in the way he is using them now. Python's emulation of signal
semantics is sufficiently different from C that you can't rely on the
same behavior. (And note that in C, signal handlers are usually
broken anyway; e.g. the code you write, which prints something inside
the signal handler, is broken on C too because you don't know the
state of stdout when the handler is invoked.)
I looked at what could be different between 1.5.1 and 1.5.2, and found
that the call to siginterrupt() to disable restarting system calls was
added after 1.5.1. Given the alternatives, I think I like the 1.5.2
behavior better than the 1.5.1 behavior.
--Guido van Rossum (home page: http://www.python.org/~guido/)