This was mentioned in ticket #77388. It turns out to be
related to #4253.
If the file cannot be opened, -T and -B on filenames set the last han-
dle to null and set the last stat type to stat, but leave the actual
stat buffer and success status as they were.
That means that stat(_) will continue to return the previous buffer,
but lstat(_) will no longer work.
This is another of those inconsistent cases where the internal stat
info is only partially set.
Originally, this code would set PL_laststatval (the success status) to
-1. Commit
25988e07 (the patch in ticket #4253) intentionally changed
this to make -T _ less suprising on read-only files.
But the patch ended up affecting -T with an explicit file name, too.
It also only partially fixed things for -T _, because the last stat
type *was* still being set.
This commit changes it to set all the stat info, for explicit file
names, or no stat info, for _ (if the previous stat was with a
file name).
sv_setpv(PL_statname, SvPV_nomg_const_nolen(sv));
really_filename:
PL_statgv = NULL;
- PL_laststype = OP_STAT;
if (!(fp = PerlIO_open(SvPVX_const(PL_statname), "r"))) {
+ if (!gv) {
+ PL_laststatval = -1;
+ PL_laststype = OP_STAT;
+ }
if (ckWARN(WARN_NEWLINE) && strchr(SvPV_nolen_const(PL_statname),
'\n'))
Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
RETPUSHUNDEF;
}
+ PL_laststype = OP_STAT;
PL_laststatval = PerlLIO_fstat(PerlIO_fileno(fp), &PL_statcache);
if (PL_laststatval < 0) {
(void)PerlIO_close(fp);
}
use Config;
-plan(tests => 46 + 27*14);
+plan(tests => 47 + 27*14);
ok( -d 'op' );
ok( -f 'TEST' );
is runperl(prog => '-T _', switches => ['-w'], stderr => 1), "",
'no uninit warnings from -T with no preceding stat';
+SKIP: {
+ my $rand_file_name = 'filetest-' . rand =~ y/.//cdr;
+ if (-e $rand_file_name) { skip "File $rand_file_name exists", 1 }
+ stat 'test.pl';
+ -T $rand_file_name;
+ ok !stat _, '-T "nonexistent" resets stat success status';
+}
+
# Unsuccessful filetests on filehandles should leave stat buffers in the
# same state whether fatal warnings are on or off.
{
}
-plan tests => 110;
+plan tests => 111;
my $Perl = which_perl();
-T _;
my $s2 = -s _;
is($s1, $s2, q(-T _ doesn't break the statbuffer));
+ lstat($tmpfile);
+ -T _;
+ ok(eval { lstat _ }, q(-T _ doesn't break lstat for unreadable file));
unlink $tmpfile;
}