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

IO::Handle's error() method doesn't detect error.

Thread Next
From:
John Wiersba
Date:
May 23, 2015 15:45
Subject:
IO::Handle's error() method doesn't detect error.
Message ID:
CAMs4ZVtSv+wtEhFEk9HsUwnbsFx0OjpAvanH5vo+6K-3uPv3mg@mail.gmail.com
Related to this topic of the email below, here is a bug with
perl5.20.2 on linux.  Apparently, IO::Handle's error() method is
worthless -- it never reports an error.  Or maybe I'm misunderstanding
it's documentation?

I caused an I/O error by ejecting the CD that was being read from.  As
you can see from the output, $fh->sysread() detected the error and $!
held an appropriate error message, but $fh->error didn't reflect that
an error had ever occurred.

I'm still looking for a reliable way to detect an error when using
readline() or getline() and thought error() might be of value, but it
doesn't look like it (see forwarded email below).

$ cat tt.pl
use strict;
use warnings;
use IO::Handle;
open my $fh, "<", shift or die "bad open: $!\n";
my $cnt = 0;
while (1) {
    my $rc = $fh->sysread($_, 10000);
    if (! $rc) {
        my $err = $fh->error ? "set" : "not set";
        die "$err: $!\n" if !defined $rc;
        last; # reached EOF
    }
    print $cnt += length, "\n";
    sleep 1;
}
print "EOF:<$cnt>\n";

$ /opt/perl tt.pl /media/U*/wubi.exe
10000
20000
30000
40000
50000
60000
70000
80000
90000
98304
not set: Input/output error

$ /opt/perl -v
This is perl 5, version 20, subversion 2 (v5.20.2) built for i686-linux

---------- Forwarded message ----------
From: John Wiersba <jrw32982@gmail.com>
Date: Sat, May 23, 2015 at 1:29 AM
Subject: Detecting a read error when using readline
To: perl5-porters@perl.org

In older doc for readline (but not in the newest doc), it mentions the idiom:

  for (;;) {
    undef $!;
    unless (defined( $line = <> )) {
       last if eof;
       die $! if $!;
     }
  }

to distinguish between EOF and a read error.  That appears to work
properly in perl 5.20.2, but it fails in perl 5.10.1 when $/ == \100,
for example (I almost wrote a bug report for this, but since it's
working in 5.20.2, I declined).  It appears to always work in every
version I've tested it in, if $/ == "\n".
My goal is use readline and still be able to *reliably* distinguish
EOF from a read error.  See also
http://www.perlmonks.org/?node_id=583432 which indicates that this
idiom was failing on Windows under some circumstances.

My questions:

- Is it possible to use readline and reliably distinguish EOF from a
read error, using an idiom which also works on older versions of perl?
- Or do I have to resort to sysread?
- Why was this idiom removed from perldoc?

My test code:

use strict;
use warnings;
$/ = \ shift if @ARGV && $ARGV[0] =~ /^\d+\z/;
my $cnt = 0;
while (1) {
   undef $!;
   if (!defined($_ = <>)) {
      die $! if $!;
      last; # reached EOF
   }
   print $cnt += length, "\n";
}
print "EOF: $cnt\n";

Thanks!
-- John

Thread Next


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