... until end-of-file is reached, whereupon the subsequent call returns undef.
If readline encounters an operating system error, $! will be set with the corresponding error message. It can be helpful to check $! when you are reading from filehandles you don't trust, such as a tty or a socket. The following example uses the operator form of readline, and takes the necessary steps to ensure that readline was successful.
Based on the documentation, readline returns undef in two cases: EOF or I/O error. In the case of EOF, $! (or errno) is not modified and will have the value it had before readline was called, since the system call(s) have not failed. In the case of an I/O error, $! will have the corresponding errno value which resulted from the failing system call. In order to distinguish them, $! must be cleared before calling readline. If $! were not cleared, then after a call to readline which reached EOF, it would still have the same value it had before the call. If that value happened to be non-zero (which your examples show can easily happen), then it would appear that readline returned undef because an I/O error occurred.for (;;) { undef $!; unless (defined( $line = <> )) { die $! if $!; last; # reached EOF } # ... }
Here is some code which demonstrates that $! retains its value from before the readline call when EOF is reached and that therefore it is essential to clear $! in order to distinguish an I/O error from EOF.
produces:#!/usr/bin/perl sub doit { open FH, shift or die "open failure: $!\n"; $! = shift; 1 while <FH>; $n = $!+0; print "n=$n s=$!\n"; } doit $0, 5; doit $0, 6; doit $0, undef;
n=5 s=I/O error n=6 s=No such device or address n=0 s=
In reply to Re^6: Best way to handle readline errors?
by jrw
in thread Best way to handle readline errors?
by jrw
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |