summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2022-08-16 15:52:04 +1000
committerTony Cook <tony@develop-help.com>2022-08-31 10:51:09 +1000
commit80c1f1e45e8ef8c27d170fae7ade41971fe20218 (patch)
tree390f74e13dccc68dadda91a6ddb4fb059010212b
parent02cf5fb76fa9ca5db8d1b04f9087dd6d0f81848e (diff)
downloadperl-80c1f1e45e8ef8c27d170fae7ade41971fe20218.tar.gz
only clear the stream error state in readline() for glob()
This would previously clear the stream error state in any case where sv_gets() failed and the error state was set. This included normal files, which meant that the fact that an error occurred was no longer reflected in the stream state. For reads from ARGV this was a no-op, since nextargv() re-opens the input stream by calling do_open6() which closes the old input stream silently. For glob() (and really only for miniperl, since File::Glob is used for a full perl) leaving the stream in an error state could be confusing for the error reporting done when do_close() fails, since it would fail if the stream has an error state, but we report it as the underlying pclose() failing due to the child process failing in some way. Since this now leaves the error state on the stream, the close() calls in the test updated by this commit would fail, changing its output. Since the result of those closes didn't seem related to the purpose of the test, I changed it not throw an error on either close() failing.
-rw-r--r--pp_hot.c9
-rw-r--r--t/lib/warnings/pp_hot4
2 files changed, 9 insertions, 4 deletions
diff --git a/pp_hot.c b/pp_hot.c
index f02c48188d..cb76dda568 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -3334,14 +3334,19 @@ Perl_do_readline(pTHX)
|| SNARF_EOF(gimme, PL_rs, io, sv)
|| PerlIO_error(fp)))
{
- PerlIO_clearerr(fp);
if (IoFLAGS(io) & IOf_ARGV) {
fp = nextargv(PL_last_in_gv, PL_op->op_flags & OPf_SPECIAL);
- if (fp)
+ if (fp) {
continue;
+ }
(void)do_close(PL_last_in_gv, FALSE);
}
else if (type == OP_GLOB) {
+ /* clear any errors here so we only fail on the pclose()
+ failing, which should only happen on the child
+ failing
+ */
+ PerlIO_clearerr(fp);
if (!do_close(PL_last_in_gv, FALSE)) {
Perl_ck_warner(aTHX_ packWARN(WARN_GLOB),
"glob failed (child exited with status %d%s)",
diff --git a/t/lib/warnings/pp_hot b/t/lib/warnings/pp_hot
index e660528b52..0e337431dd 100644
--- a/t/lib/warnings/pp_hot
+++ b/t/lib/warnings/pp_hot
@@ -237,8 +237,8 @@ $a = <FOO> ;
use warnings 'io' ;
$a = <FOO> ;
$a = <FH> ;
-close (FH) or die $! ;
-close (FOO) or die $! ;
+close (FH);
+close (FOO);
unlink $file ;
EXPECT
Filehandle FH opened only for output at - line 5.