Subject: | read_file and write_fail can fail due to EINTR |
I encountered a bug (or misfeature) when using File::Slurp's read_file
within an app that receives signals. read_file uses sysread which is
vulnerable to being interrupted when a signal is received. Since
sysread is the raw OS read call, Perl doesn't automatically restart the
read as it does for the read function. I've attached a patch which
resolves the issue for me on my system. Also, as a caveat, I noticed
that you've been working towards supporting earlier versions of Perl in
File::Slurp and I've not been able to test it on anything other than
the 5.8 train.
The same issue likely exists with write_file as well, though I did not
experience it. I included a fix for it in my patch as well.
Subject: | file-slurp-eintr.patch |
diff -ru File-Slurp-9999.12/lib/File/Slurp.pm File-Slurp-9999.12.acd/lib/File/Slurp.pm
--- File-Slurp-9999.12/lib/File/Slurp.pm 2006-02-17 01:13:51.000000000 -0500
+++ File-Slurp-9999.12.acd/lib/File/Slurp.pm 2007-08-24 11:29:15.696387979 -0400
@@ -6,6 +6,7 @@
use POSIX qw( :fcntl_h ) ;
use Fcntl qw( :DEFAULT ) ;
use Symbol ;
+use Errno ;
my $is_win32 = $^O =~ /win32/i ;
@@ -174,6 +175,10 @@
next ;
}
+# since we're using sysread Perl won't automatically restart the call when
+# interrupted by a signal.
+ next if $!{EINTR};
+
# handle the read error
@_ = ( \%args, "read_file '$file_name' - sysread: $!");
@@ -330,6 +335,10 @@
my $write_cnt = syswrite( $write_fh, ${$buf_ref},
$size_left, $offset ) ;
+# since we're using sysread Perl won't automatically restart the call when
+# interrupted by a signal.
+ next if $!{EINTR};
+
unless ( defined $write_cnt ) {
# the write failed