connect SIGINT to custom interrupt handler

Nobody nobody at nowhere.com
Sun May 15 22:53:22 EDT 2011


On Sun, 15 May 2011 14:32:13 +0000, Christoph Scheingraber wrote:

> I now have signal.siginterrupt(signal.SIGINT, False) in the line
> below signal.signal(signal.SIGINT, interrupt_handler)
> 
> Unfortunately, pressing ^c still results in the same interrupt error.

Sorry; I wasn't paying sufficient attention to the details:

>>> select.error: (4, 'Interrupted system call')

According to Linux' signal(7) manpage, select() is never restarted,
regardless of the siginterrupt() setting.

In general, wait-for-something functions aren't restarted; the caller is
expected to check that the waited-for condition actually happened, so
returning prematurely isn't considered problematic.

EINTR is one of those "special" errors (like EAGAIN) which don't
actually indicate an error. In the context of select(), a return value of
-1 with errno set to EINTR should normally be handled in the same way as a
return value of zero, i.e. "nothing has happened yet, try again".

While the EINTR case isn't identical to the zero-return case, it's much
closer to it than it is to a genuine error. If it's being treated like
genuine errors (i.e. raising an exception), that's a defect in the Python
bindings. In which case, I'd suggest catching the exception and checking
the error code, e.g.:

def myselect(rlist, wlist, xlist, timeout = None):
    try:
        return select.select(rlist, wlist, xlist, timeout)
    except select.error, e:
        if e[0] == errno.EINTR:
            return 0
        raise




More information about the Python-list mailing list