diff options
author | Zefram <zefram@fysh.org> | 2017-11-15 08:11:37 +0000 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2017-11-15 08:11:37 +0000 |
commit | 97c8f3e6ed903d7d1ab2b973a137ff8412e94c87 (patch) | |
tree | c877853bce7868d8ce13a867cebc85d0b0ae119b /pp_sys.c | |
parent | aa2bc4d385298947b20667efc390d3182feaebe1 (diff) | |
download | perl-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 'pp_sys.c')
-rw-r--r-- | pp_sys.c | 22 |
1 files changed, 13 insertions, 9 deletions
@@ -2915,10 +2915,11 @@ PP(pp_stat) Perl_croak(aTHX_ "The stat preceding lstat() wasn't an lstat"); } - if (gv != PL_defgv) { - bool havefp; + if (gv == PL_defgv) { + if (PL_laststatval < 0) + SETERRNO(EBADF,RMS_IFI); + } else { do_fstat_have_io: - havefp = FALSE; PL_laststype = OP_STAT; PL_statgv = gv ? gv : (GV *)io; SvPVCLEAR(PL_statname); @@ -2929,22 +2930,25 @@ PP(pp_stat) if (IoIFP(io)) { int fd = PerlIO_fileno(IoIFP(io)); if (fd < 0) { + report_evil_fh(gv); PL_laststatval = -1; SETERRNO(EBADF,RMS_IFI); } else { PL_laststatval = PerlLIO_fstat(fd, &PL_statcache); - havefp = TRUE; } } else if (IoDIRP(io)) { PL_laststatval = PerlLIO_fstat(my_dirfd(IoDIRP(io)), &PL_statcache); - havefp = TRUE; } else { + report_evil_fh(gv); PL_laststatval = -1; + SETERRNO(EBADF,RMS_IFI); } - } - else PL_laststatval = -1; - if (PL_laststatval < 0 && !havefp) report_evil_fh(gv); + } else { + report_evil_fh(gv); + PL_laststatval = -1; + SETERRNO(EBADF,RMS_IFI); + } } if (PL_laststatval < 0) { @@ -3489,7 +3493,7 @@ PP(pp_fttty) else if (name && isDIGIT(*name) && grok_atoUV(name, &uv, NULL) && uv <= PERL_INT_MAX) fd = (int)uv; else - FT_RETURNUNDEF; + fd = -1; if (fd < 0) { SETERRNO(EBADF,RMS_IFI); FT_RETURNUNDEF; |