From 7683e280de4f493687397ccafc0eee4315b29321 Mon Sep 17 00:00:00 2001 From: Max Maischein Date: Sun, 28 Jun 2020 18:55:26 +0200 Subject: [PATCH] Signal readdir() errors by clearing/setting errno At least for Linux, distinguishing an error from the end of the directory listing is done by setting errno to 0 and then calling readdir(). Errno will then be set in the case of an error. https://linux.die.net/man/3/readdir This adresses https://github.com/Perl/perl5/issues/17907 but unfortunately, there are no tests to (re)produce the behaviour at all. $! mirrors errno, so there also is added code in the example in perlfunc.pod how to check for an error condition. --- pod/perlfunc.pod | 4 ++++ pp_sys.c | 1 + 2 files changed, 5 insertions(+) diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index e95c54f42528..124144836e08 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -6295,6 +6295,8 @@ value, not for its regular truth value. while (readdir $dh) { print "$some_dir/$_\n"; } + die "Got error while reading '$some_dir': $!" + if $!; closedir $dh; To avoid confusing would-be users of your code who are running earlier @@ -6304,6 +6306,8 @@ recent vintage: use 5.012; # so readdir assigns to $_ in a lone while test +In the case of an error, C will be returned and $! will be non-zero. + =item readline EXPR =item readline diff --git a/pp_sys.c b/pp_sys.c index a431bbe30bae..4b357d4a43cb 100644 --- a/pp_sys.c +++ b/pp_sys.c @@ -4041,6 +4041,7 @@ PP(pp_readdir) } do { + SETERRNO(0,0); dp = (Direntry_t *)PerlDir_read(IoDIRP(io)); if (!dp) break;