summaryrefslogtreecommitdiff
path: root/doio.c
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2017-11-15 08:11:37 +0000
committerZefram <zefram@fysh.org>2017-11-15 08:11:37 +0000
commit97c8f3e6ed903d7d1ab2b973a137ff8412e94c87 (patch)
treec877853bce7868d8ce13a867cebc85d0b0ae119b /doio.c
parentaa2bc4d385298947b20667efc390d3182feaebe1 (diff)
downloadperl-97c8f3e6ed903d7d1ab2b973a137ff8412e94c87.tar.gz
set $! when statting a closed filehandle
When a stat fails because it's on a closed or otherwise invalid filehandle, $! was often not being set, depending on the operation and the nature of the invalidity. Consistently set it to EBADF. Fixes [perl #108288].
Diffstat (limited to 'doio.c')
-rw-r--r--doio.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/doio.c b/doio.c
index 9aba9dc949..7dcbbb5cfb 100644
--- a/doio.c
+++ b/doio.c
@@ -1779,8 +1779,11 @@ Perl_my_stat_flags(pTHX_ const U32 flags)
if (PL_op->op_flags & OPf_REF) {
gv = cGVOP_gv;
do_fstat:
- if (gv == PL_defgv)
+ if (gv == PL_defgv) {
+ if (PL_laststatval < 0)
+ SETERRNO(EBADF,RMS_IFI);
return PL_laststatval;
+ }
io = GvIO(gv);
do_fstat_have_io:
PL_laststype = OP_STAT;
@@ -1791,6 +1794,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags)
int fd = PerlIO_fileno(IoIFP(io));
if (fd < 0) {
/* E.g. PerlIO::scalar has no real fd. */
+ SETERRNO(EBADF,RMS_IFI);
return (PL_laststatval = -1);
} else {
return (PL_laststatval = PerlLIO_fstat(fd, &PL_statcache));
@@ -1801,6 +1805,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags)
}
PL_laststatval = -1;
report_evil_fh(gv);
+ SETERRNO(EBADF,RMS_IFI);
return -1;
}
else if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t))
@@ -1853,6 +1858,8 @@ Perl_my_lstat_flags(pTHX_ const U32 flags)
if (cGVOP_gv == PL_defgv) {
if (PL_laststype != OP_LSTAT)
Perl_croak(aTHX_ "%s", no_prev_lstat);
+ if (PL_laststatval < 0)
+ SETERRNO(EBADF,RMS_IFI);
return PL_laststatval;
}
PL_laststatval = -1;
@@ -1862,6 +1869,7 @@ Perl_my_lstat_flags(pTHX_ const U32 flags)
"Use of -l on filehandle %" HEKf,
HEKfARG(GvENAME_HEK(cGVOP_gv)));
}
+ SETERRNO(EBADF,RMS_IFI);
return -1;
}
if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t))