feof status (was: Re: [Python-Dev] Rehabilitating fgets)

Eric S. Raymond esr@thyrsus.com
Sun, 7 Jan 2001 13:45:41 -0500


Guido van Rossum <guido@python.org>:
> > This mess reminds me.  For some work I'm doing right now, it would be
> > very useful if there were a way to query the end-of-file status of a
> > file descriptor without actually doing a read.
> 
> I hope you really mean file object (== wrapper around stdio FILE
> object).  A file descriptor (small little integer in Unix) doesn't
> have a way to find this out.

You're right, my bad.
 
> Even for file objects, it is typically only known that there's an EOF
> condition after a lowest-level read operation returned 0 bytes.  So in
> effect you must still do a read in order to determine EOF status.
> 
> I just ran a small test program, and fread() appears to set the eof
> status when it returns a short count.  Normally, Python's read() uses
> fread() so this might be useful.  However after a readline(), you
> can't know the eof status (unless the last line of the file doesn't
> end in a newline).

I considered trying a zero-length read() in Python, but this strikes me 
as inelegant even if it would work.

> Before adding an eof() method, can you explain what your program is
> trying to do?  Is it reading from a pipe or socket?  Then select() or
> poll() might be useful.

Sadly, it's exactly the wrong case.  Hmmm...omitting irrelevant details,
it's a situation where a markup file can contain sections in two different
languages.  The design requires the first interpreter to exit on seeing
either EOF or a marker that says "switching to second language".  For
reasons too compllicated to explain, it would be best if the parser for
the first language didn't simply call the second parser.

The logic I wanted to write amounts to:

while 1:
    line = fp.readline()
    if not line or line == "history":
        break
    interpret_in-language_1(line)

if not fp.feof()
    while 1:
        line = fp.readline()
        if not line:
            break
    	interpret_in-language_2(line)

I just tested the zero-length-read method.  That worked.  I guess I'll
use it.
-- 
		<a href="http://www.tuxedo.org/~esr/">Eric S. Raymond</a>

"Today, we need a nation of Minutemen, citizens who are not only prepared to
take arms, but citizens who regard the preservation of freedom as the basic
purpose of their daily life and who are willing to consciously work and
sacrifice for that freedom."
	-- John F. Kennedy