develooper Front page | perl.perl5.porters | Postings from May 2004

Re: [perl #29277] eof() on non-blocking filehandle

Thread Previous
From:
perl5-porters
Date:
May 5, 2004 06:22
Subject:
Re: [perl #29277] eof() on non-blocking filehandle
Message ID:
c7app2$nbm$1@post.home.lunix
In article <20040504215002.GE1884@iabyn.com>,
	Dave Mitchell <davem@iabyn.com> writes:
> Perl's eof is implemneted by going a getc and ungetc equivalent;
> since these can change $!, but the Perl function eof() is documented
> as not seeing $!, the old value has to be saved then restored.
> Agin, the value of $! here is a bit of red herring.
>
Well, not completely. Indeed $! only gets a guaranteed value after 
a failing systemcall, and stdio functions aren't even systemcalls. 
However, the way it normally works is that perl doesn't play with $! 
(or errno at the C level really), and just lets libc do its job. 
In particular if I use perl operators corresponding to stdio functions, 
I usually expect $! to show what the corresponding stdio function 
would return. 

But yeah, that's just an expectation, not guaranteed in the perl docs, 
so I wasn't calling the $! behaviour a bug. But still, I find the 
save/restore behaviour that eof() does on $! unexpected and it also 
seems pointless (my version of the eof() docs (perl 5.8.2) at least 
don't say that $! gets saved and restored).

> The real issues, are whether eof() should be clever enough to understand
> and handle non-blocking I/O (I presume that EAGAIN is system specific, at
> least outside the UNIX world!), or whether this falls into the category
> of mixing raw and buffered I/O, and thus get everything you deserve?
>

Using stdio functions on non-blocking sockets is not what I personally
would do, but it's a valid programming style nevertheless.
However it works at the systemcall level not visible for the perl user,
I think eof() should return some false value for the case of a non-closed
non-blocking socket (undef would be my personal preference), and while
$! probably won't be documented as anything particular, naively I would 
expect to see EAGAIN. And by not trying to be clever about $! save/restore, 
I think that would actually happen automatically.

Trying to formulate what I'd want to happen purely in terms of 
getc/ungetc, I also notice that if in my test program I replace 
eof($rd) with getc($rd), I see:

undef/Bad file descriptor

in both cases (closed or non-closed non-blocking socket). The getc() docs
DO talk about $!, but only say that in the error case it will have a value.
It implies (but indeed doesn't say) that for the eof case, $! should be
empty, otherwise you cannot distinguish the two cases (error versus eof).

And "Bad file descriptor" is even a very unexpected error for the 
non-closed case (where supposedly the docs say I should get a valid $!). 
It's not the correct errno nor does an strace show any EBADF happening on 
any of the system calls.

Thread Previous


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