summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2013-12-12 16:22:06 +1100
committerTony Cook <tony@develop-help.com>2013-12-18 13:42:53 +1100
commitee71f1d151acd0a4c10ebcec28f0798178529847 (patch)
tree4be0e61b90cc8e3204ea1fc66083f25ec3fee819
parent6b0ff4b4f2542a206738f2f065066e9bf895cbf4 (diff)
downloadperl-ee71f1d151acd0a4c10ebcec28f0798178529847.tar.gz
[perl #118651] don't overwrite $! in readdir()
POSIX expects readdir() to leave errno alone when it reaches end of directory without an error so that case can be detected. Do the same in perl.
-rw-r--r--pp_sys.c2
-rw-r--r--t/op/readdir.t18
2 files changed, 19 insertions, 1 deletions
diff --git a/pp_sys.c b/pp_sys.c
index 6f4c198d49..74b65f7b67 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3858,7 +3858,7 @@ PP(pp_readdir)
} while (gimme == G_ARRAY);
if (!dp && gimme != G_ARRAY)
- goto nope;
+ RETPUSHUNDEF;
RETURN;
diff --git a/t/op/readdir.t b/t/op/readdir.t
index 528a0f1e0c..8515d1d9d0 100644
--- a/t/op/readdir.t
+++ b/t/op/readdir.t
@@ -67,4 +67,22 @@ fresh_perl_like(<<'EOP', qr/^no crash/, {}, 'RT #68182');
print "no crash";
EOP
+SKIP:
+{ # [perl #118651]
+ # test that readdir doesn't modify errno on successfully reaching the end of the list
+ # in scalar context, POSIX requires that readdir() not modify errno on end-of-directory
+ my @s;
+ ok(opendir(OP, "op"), "opendir op");
+ $! = 0;
+ while (defined(my $f = readdir OP)) {
+ push @s, $f
+ if $f =~ /^[^\.].*\.t$/i;
+ }
+ my $errno = $! + 0;
+ closedir OP;
+ is(@s, @D, "should be the same number of files, scalar or list")
+ or skip "mismatch on file count - presumably a readdir error", 1;
+ is($errno, 0, "errno preserved");
+}
+
done_testing();