Re: Generating a readline error
by BrowserUk (Patriarch) on Jul 17, 2009 at 16:50 UTC
|
open NUL, '<', 'nul' or die $!;;
defined( $s = readline( NUL )) or die $!;;
[Died at (eval 9) line 1.
Or
open O, '>', 'nul' or die $!;;
defined( $s = readline( O )) or die $!;;
Filehandle O opened only for output at (eval 11) line 1.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
|
You're misreporting eof as an error.
| [reply] |
|
|
Thanks, the method used in the second snippet (added since my original reply) will be useful to me. It's even portable (using the appropriate device name)!
It would be ideal if I had a means of generating an error after doing some valid reads, but I can make do without.
| [reply] |
|
|
I guess you could read for awhile and then close the filehandle. It is possible to open 2 filehandles to same file. Close one and keep going with the other one after first bombs. My seek idea didn't work as seek past EOF is not an error (that's how to generate "sparse files"). I've tested that on Perl before (*nix and even XP) and it works fine and you just get EOF if you read something like that. Of course EOF is not an error. And of course a write past EOF is completely legal and produces no error. I've written device drivers that will pass back "known bad data" from say disk system. But that's a special thing and drivers,O/S,app have to know what's going on. That sort of thing is used in huge volume data applications where say 12 bits wrong won't matter in say a video image or a seismic data app. Still curious as to what kind of data recovery is possible in typ Perl app after "bad data" from an I/O device?
| [reply] |
|
|
|
|
That seems to die at the open, not the readline.
| [reply] |
|
|
#!/usr/bin/perl -w
use strict;
open (IN, "asdf"); #this fails but return code ignored
print while (<IN>); #readline() on closed filehandle
#IN at C:\TEMP\ioerror.pl line 6.
| [reply] [d/l] |
|
|
|
|
|
Re: Generating a readline error
by ikegami (Patriarch) on Jul 17, 2009 at 18:28 UTC
|
I should have checked the docs for the underlying system call! Possible failure modes for read on this system:
- EAGAIN
- Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.
- EBADF
- fd is not a valid file descriptor or is not open for reading.
- EFAULT
- buf is outside your accessible address space.
- EINTR
- The call was interrupted by a signal before any data was read.
- EINVAL
- fd is attached to an object which is unsuitable for reading; or the file was opened with the O_DIRECT flag, and either the address specified in buf, the value specified in count, or the current file offset is not suitably aligned.
- EIO
- I/O error. This will happen for example when the process is in a background process group, tries to read from its controlling tty, and either it is ignoring or blocking SIGTTIN or its process group is orphaned. It may also occur when there is a low-level I/O error while reading from a disk or tape.
- EISDIR
- fd refers to a directory.
Using non-blocking IO might do the trick. Or maybe closing the underlying fd using POSIX::close.
| [reply] [d/l] [select] |
|
|
Lots of these things like EAGAIN aren't really "errors", somebody doing that would be expected to handle this situation. aysnc read/write is common in realtime systems.
Some of these things like EFAULT, can't be done as a user (O/S) won't allow it.
One simple idea for you is to setup some I/O intensive thing on a flash drive. Then reach down and unplug that thing. This will look like disk drive died midstream and some kind of error will happen. Depending upon file system, timing of this, etc. the result might be even complete loss of all data on that stick. But if it formatted to look like a hard drive, then I think you can set up (maybe with a few ties) something like looks like EIO (bad sector) because the "checksum" for that sector will be wrong. If I'm right, then you have a known bad file on a "disk drive" that you can test with. Setup up loop with write intensive thing, unplug drive, then see if you can read all files after you reset program, replug in and try reading. May take a couple of tries to hit this right and get desire effect.
| [reply] |
|
|
| [reply] |
|
|
Re: Generating a readline error
by MidLifeXis (Monsignor) on Jul 17, 2009 at 16:43 UTC
|
Is there some sort of mock IO object available? How about a tie interface with the real IO object on the back end, but injecting your errors at the right point?
Update: Data::Storage::Mock perhaps?
--MidLifeXis
The tomes, scrolls etc are dusty because they reside in a dusty old house, not because they're unused. --hangon in this post
| [reply] [d/l] |
|
|
I'm testing Perl itself, so using a tied object is not ideal.
| [reply] |
|
|
| [reply] |
|
|
|
|
|
Re: Generating a readline error
by ig (Vicar) on Jul 17, 2009 at 20:45 UTC
|
On linux I created a small file system on a loop device, filled it with a single file then truncated the underlying file. After deleting and recreating the loop device (I suppose this flushed cashed data), reading the contained file resulted in several successful reads followed by a read failure with EBADF.
| [reply] |