For some reason, siginterrupt() only seems to set the behaviour for the first signal received.
In this example program, the first SIGQUIT appears to do nothing, but the second sigquit prints “SIGQUIT Handler” and s.accept() throws an Interrupted system call exception.
from signal import *
from socket import *
import sys
def sigquitHandler(signum, frame):
print("SIGQUIT Handler")
s = socket()
s.bind(("0.0.0.0", int(sys.argv[1])))
s.listen(5)
signal(SIGQUIT, sigquitHandler)
siginterrupt(SIGQUIT, False)
client, addr = s.accept() # Or any syscall that blocks
client.close()
s.close()
What am i misunderstanding here?
Edit: Here’s something else that i can’t figure out, in this program, a SIGQUIT interrupts the select(). Is that supposed to happen?
from signal import *
import select
import sys
def sigquitHandler(signum, frame):
print("SIGQUIT Handler")
signal(SIGQUIT, sigquitHandler)
siginterrupt(SIGQUIT, False)
select.select([sys.stdin], [], [])
Which
unixare you using? At theClevel, there are different implementations and semantics for signal handling on BSD vs System 5 (SYSV).My guess is that you are using SYSV, in which case the signal disposition is reset to SIG_DFL after the signal handler has returned (classical signal handling). On SYSV you need to call
signalin the handler to reinstall that handler.Python more or less provides BSD style signal handling. So, on a SYSV OS, Python must be managing reinstallation of the signal handler via
signal. Now, according to the Python doco forsiginterrupt:And there you go – if Python is automatically reinstalling your signal handler (to provide BSD like semantics), it may well be doing so in a way that implicitly calls
siginterrupt(1).Of course, my guess could be wrong.
You might be able to fix this by defining sigquitHandler like this:
It depends on when and how Python is restoring the signal disposition.
EDIT
Adding
siginterrupt(SIGQUIT, False)to the signal handler has no affect.EDIT 2
After some more poking around in the Python2.6 source code it clear that this is not just a SYSV issue. It will affect BSD systems too.