This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #126229] POSIX::strerror() clears $!
authorDavid Mitchell <davem@iabyn.com>
Tue, 13 Oct 2015 11:12:37 +0000 (12:12 +0100)
committerDavid Mitchell <davem@iabyn.com>
Tue, 13 Oct 2015 11:18:20 +0000 (12:18 +0100)
If POSIX::strerror is passed $! as its arg, then it ends up doing
local $! = $!, which due to a bug in the localisation system, leaves $!
undef even after scope exit.

Work around the bug by assigning $_[0] to a my var first.

ext/POSIX/lib/POSIX.pm
ext/POSIX/t/strerror_errno.t

index 71b2d66..bb563bb 100644 (file)
@@ -4,7 +4,7 @@ use warnings;
 
 our ($AUTOLOAD, %SIGRT);
 
-our $VERSION = '1.57';
+our $VERSION = '1.58';
 
 require XSLoader;
 
@@ -151,7 +151,7 @@ my %reimpl = (
     exit      => 'status => CORE::exit($_[0])',
     getenv    => 'name => $ENV{$_[0]}',
     system    => 'command => CORE::system($_[0])',
-    strerror  => 'errno => BEGIN { local $!; require locale; locale->import} local $! = $_[0]; "$!"',
+    strerror  => 'errno => BEGIN { local $!; require locale; locale->import} my $e = $_[0] + 0; local $!; $! = $e; "$!"',
     strstr    => 'big, little => CORE::index($_[0], $_[1])',
     chmod     => 'mode, filename => CORE::chmod($_[0], $_[1])',
     fstat     => 'fd => CORE::open my $dup, "<&", $_[0]; CORE::stat($dup)', # Gross.
index 4807a8d..df691f1 100644 (file)
@@ -14,4 +14,11 @@ $! = 1;
 POSIX::strerror(1);
 is (0+$!, 1, 'strerror doesn\'t destroy $!');
 
+# [perl #126229] POSIX::strerror() clears $!
+{
+    local $! = 29;
+    my $e = POSIX::strerror($!);
+    is (0+$!, 29);
+}
+
 done_testing();