develooper Front page | perl.perl5.porters | Postings from August 2008

How to tell whether readline got an error or EOF

From:
Ed Avis
Date:
August 2, 2008 06:15
Subject:
How to tell whether readline got an error or EOF
Message ID:
loom.20080802T130048-14@post.gmane.org
I have been writing a tied filehandle class to illustrate my suggestion of how
magic ARGV processing should work, but while doing so I came across this puzzle:

sub READLINE {
    my $self = shift;
    my $underlying_fh = $self->{fh};
    my $line = <$underlying_fh>;
    if (not defined $line) {
        # Either end of file, or reading failed with an error.
        # How do I tell which is which?
        #
    }
}

perlfunc says that readline will set $! on error.  But $! might have some stale
value from a previous system call, so I cannot simply call readline and then
test if $! is set.  That would be possible, however, if readline also promised
to clear $! if there is no error: is that the case?

Another way would be to explicitly test EOF after trying to read a line.  But
that is not quite correct if someone else is modifying the file at the same time.

If I call readline, how can I reliably tell the difference between error and
EOF?  And how should my tied filehandle class provide that same postcondition to
its user?

I note that getc() has the same problem: on error it returns undef and sets $!,
on EOF it returns error and leaves $! with the same value it had before.

% echo x | perl -e 'getc; print $!; print 0; open FH, "nonexistent"; getc; print
$!; print 0; getc; print $!'
0No such file or directory0Bad file descriptor

The first two getc calls succeed because echo prints two characters (x and
newline), but the second of them, even though it succeeded, leaves $! with the
leftover error code from the open() call earlier.  The third getc sets $! to
'Bad file descriptor'.  Is that the magic code for end of file?  Is it possible
to get a 'Bad file descriptor' error from getc in situations other than EOF, and
if so how do you reliably tell the difference?

I've only tested this with 5.6 and 5.8, so apologies if it is fixed (either the
documentation or the behaviour) already in 5.10.


-- 
Ed Avis <eda@waniasset.com>




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About