Question about read() behavior and EINTR

Chris Jaeger cjaeger at ensim.com
Tue Oct 9 18:24:35 EDT 2001


	Hrm... I've just realized that I'm probably getting
a SIGCHLD from the child process generating the data (which
means somewhere I must have registered a handler for it). So, I
could solve this by setting up the signal handler for SIGCHLD
to restart system calls. However, I'm still wondering if
python should have thrown the IOError earlier (back when
errno was still set). And what should the behavior be if the
signal weren't SIGCHLD?

Thanks,
Chris

Chris Jaeger wrote:
> 
> Hi all,
> 
>         I've encountered an annoying behavior with respect to
> the built-in read() function and I'm wondering whether it is
> a Python bug, a glibc bug, or a case of abusing read(). For
> reference, I'm using Python 2.1.1 on a glibc-2.2.2 Linux
> system, with kernel 2.4.2.
> 
>         I have a python extension module written in C that
> executes commands via execl, and returns the stdin, stdout,
> and stderr as Python file objects. With one particular
> command sequence, my code received an IOError exception
> with errno set to 0. I started digging down,  and this is
> what I've reconstructed about the sequence of events:
> 
>  - from python:
>    data = stdout.read(16384)
>    while data:
>        <do something with data>
>        data = stdout.read(16384)
> 
>    Three read()s occur, with the following behavior:
>    stdout.read(16384) returns 12288 bytes
>    stdout.read(16384) returns 1266 bytes
>    stdout.read(16384) throws IOError(0, 'Error')
> 
>    I added some tracing code into the python binary and
> noticed that the error bit in the FILE structure is set
> during the first read, and this is what eventually causes
> the IOError to be thrown. Here is a more detailed sequence:
> 
>    stdout.read(16384)
>      file_read(16384)
>        fread(16384)
>          read(16384) returns 12288 bytes
>          read(4096) returns EINTR, causing glibc to set error bit in
> FILE
>        fread returns 12288 bytes
>      file_read returns 12288 bytes
>    stdout.read returns 12288 bytes
>    stdout.read(16384)
>      file_read(16384)
>        fread(16384)
>          read(16384) returns 1266 bytes
>          read(15118) returns 0, setting EOF bit in FILE
>        fread returns 1266 bytes
>      file_read returns 1266 bytes
>    stdout.read returns 1266 bytes
>    stdout.read(16384)
>      file_read(16384)
>        fread(16384)
>        fread returns 0
>      file_read notes 0 return value and checks ferror()
>        ferror() returns true (due to EINTR, way back in the first call)
>      file_read sets up exception and returns
>    stdout.read throws IOError
> 
>         So, any ideas as to who is at fault? Should glibc see EINTR
> and not bother setting the error bit? Should python check feof() in
> preference to ferror()? Should I be setting up signal handlers to
> restart the read system call? Any ideas are appreciated.
> 
> Thanks,
> Chris
> 
> --
> http://mail.python.org/mailman/listinfo/python-list




More information about the Python-list mailing list