I/O status Re: SPUG: proper checking of file status after read?

Fred Morris m3047 at inwa.net
Thu Sep 18 22:12:48 CDT 2003


This wouldn't be something beyond theoretical concern, except on continued
analysis the SPOF leads back to I/O error: in other words since everything
is templated, errors reading templates would result in downline errors with
parameters on subsequent GETs/POSTs.

Not saying that the theoretical issue wouldn't personally irritate me..
because it would.. but I would figure some grandiose inefficiency covered
for it, such as reading in the entire file on open, such that any I/O error
would be reflected there, or something like that. Did I mention that some
warns don't seem to show? No, I didn't.

For the most part then, Ben's reportage is without blame, although its
applicability to the real world can be questioned.

At 9:08 AM 9/18/03, Ben Reser wrote:
>On Wed, Sep 17, 2003 at 08:46:29PM -0700, Fred Morris wrote:
>> This brings up a question about the code which is being executed, and if it
>> is correct.
>>
>>
>>     open( INFILE, '/path/spec') ... no errors, notice no mode == read
>>
>>     while ($line = <INFILE>) {
>>
>>       all ok...
>>     }
>>
>>     if ($!) ... <--- this is what sporadically fails!
>>
>>
>> The point is to determine that the file was read ok. If not like this, then
>> how? Is $! unsafe/indeterminate when a file has been successfully read?
>>
>> I don't see this behavior on my stable server, which is running older stuff.
>>
>> If anybody's got any insights to share....
>
>Per perlvar:
>If used numerically, yields the current value of the C "errno"
>variable, or in other words, if a system or library call fails,
>it sets this variable.  This means that the value of $! is
>meaningful only immediately after a failure:
>if (open(FH, $filename)) {
>    # Here $! is meaningless.
>    ...
>} else {
>    # ONLY here is $! meaningful.
>    ...
>    # Already here $! might be meaningless.
>}
># Since here we might have either success or failure,
># here $! is meaningless.

In the real world, this has never been the case, but thanks for pointing it
out. This sounds like bad documentation more than anything else: there are
side effects which call system libraries which mere mortals are unaware or
uninformed of. (Nobody's encountered crufty and perhaps slightly arrogant
documentation before?) Or are we to believe that $! is used merely for
scratch when the whim strikes?

>In the above meaningless stands for anything: zero, non-zero,
>"undef".  A successful system or library call does not
>set the variable to zero.
>
>So yes, your code is wrong.  The better way to write this is:
>open (INFILE, '/path/spec') or die "Couldn't open /path/spec: $!";

Herein is the allusion to buffering gone bad... (do that, doesn't fail)

>@lines = <INFILE> or die "Error reading /path/spec: $!";

How is this different from a while loop on individual lines until
(presumably) an undef occurs? In the newer versions of Perl, (no I stand
corrected, any version of Perl 5) this would fail if the file was empty.
However, if there was no error, are you saying that $! is "meaningless"?
This is the snag, you see.

And it's not just "any value", it's an ioctl.. every time.


As a matter of fact, I just tried your suggestion on an empty file with
perl v5.8.0 i586-linux-thread-multi (plus SuSE patches) and by golly I got
Inappropriate ioctl for device.

On 5.005_03 $! is .. well... false.

Anything else I missed here? Yes. The system with 5.5.3 is on an ext2 fs,
and the system with 5.8.0 is reiserfs. FWIW.


But again: I am sure that the file(s) in question in the real app are *not*
empty. How does one check for a "no problem" condition when at end of
file.. because we can ascertain, by both documentation and practice, that
"end of file" is reached when the end of file is reached as well as when
there is an I/O error.

Am I a flipper baby for wanting to be able to check for I/O read status?
Does nobody do this? Wow.

--

Fred Morris
m3047 at inwa.net





More information about the spug-list mailing list