[Python-Dev] Signal-resistant code (was: Two random and nearly unrelated ideas)

Guido van Rossum guido@python.org
Wed, 04 Sep 2002 15:16:25 -0400


> > what is EINTER-safe?
> 
> When an I/O operation is interrupted by an unmasked signal it returns 
> with errno==EINTR.  The state of the file is not affected and repeating
> the operation should recover and continue with no loss of data.

What if the operation is a select() call?  Is restarting the right
thing?  How to take into account the consumed portion of the timeout,
if given?

> Here is an EINTR-safe version of read:
> 
> ssize_t safe_read(int fd, void *buf, size_t count) {
> 	ssize_t result;
> 	do {
> 		result = read(fd, buf, count);
> 	} while (result == -1 && errno == EINTR);
> 	return result;
> }
> 
> When exposing the C I/O calls to Python you can either:
> 
> 1. Use EINTR-safe I/O and hide this from the user.
> 2. Pass on EINTR to the user.
> 
> Python currently does #2 with a big caveat - the internal buffering 
> of functions like file.read or file.readline is messed up and cannot be 
> cleanly restarted. This makes signals unusable for delivery of asynchronous 
> events in the background without affecting the state of the main program.

Can you point to a place in the code where this is happening?

Or is this a stdio problem?  I believe that calls like fgets() and
getchar() don't lose data, but maybe I misunderstand your observation.

As I said before, I'm very skeptical that making the I/O ops
EINTR-safe would be enough to allow the use of signals as siggested by
Skip, but that might still be useful for other purposes, *if* we can
decide when to honor EINTR and when not.

--Guido van Rossum (home page: http://www.python.org/~guido/)