Front page | perl.perl5.porters |
Postings from August 2006
Re: [perl #8244] *FILE{IO} does not behave like *FILE for stat()and -X() operators
Thread Previous
|
Thread Next
From:
Andrew Dougherty
Date:
August 9, 2006 12:15
Subject:
Re: [perl #8244] *FILE{IO} does not behave like *FILE for stat()and -X() operators
Message ID:
Pine.LNX.4.62.0608091448460.14322@fractal.phys.lafayette.edu
On Thu, 27 Jul 2006, Steve Peters via RT wrote:
> On Tue Jan 15 00:10:56 2002, jamie wrote:
> > This is a bug report for perl from jamie@shareable.org,
> > generated with the help of perlbug 1.28 running under perl v5.6.0.
> >
> >
> > Although this works fine with functions like `read', `write',
> > `sysread'
> > etc., it generates an unexpected result with `stat', `lstat' and the
> > `-X' file test operators.
> >
> > Specifically, when one of these *FILE{IO} references is used in the
> > file
> > test functions, including `stat' and `lstat', it's converted to a
> > string
> > (i.e. "IO::Handle=IO(0x12345678)"), and that is used as the file name
> > to
> > test.
> >
> > On the other hand, when a typeglob *FILE is used in a file test
> > function, the fstat() system call is used on the open file as
> > expected.
> >
> Sorry about not responding to this earlier. This problem has been fixed
> with change #28628.
Thanks (and sorry to bother the original poster with yet another
follow-up) but there's a subtle problem (actually discovered by Coverity).
Specifically, in this bit of code (starting around line 2839)
SV* const sv = POPs;
if (SvTYPE(sv) == SVt_PVGV) {
gv = (GV*)sv;
goto do_fstat;
} else if(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
gv = (GV*)SvRV(sv);
if (PL_op->op_type == OP_LSTAT)
goto do_fstat_warning_check;
goto do_fstat;
} else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) {
io = (IO*)SvRV(sv);
if (PL_op->op_type == OP_LSTAT)
goto do_fstat_warning_check;
goto do_fstat_have_io;
}
the last clause can end up doing a 'goto do_fstat_warning_check' without
ever setting gv. That warning check can indeed try to dereference gv.
The following test script (stripped down from t/op/stat.t) illustrates the
problem. It currently core dumps at the XXX line while trying to warn
"lstat() on filehandle %s", GvENAME(gv), and dumps core since gv is NULL.
I haven't dug deeply enough to decide whether to just beef up the warning
message (and the corresponding perldiag entry) or whether there's some way
to make some more useful information available.
#!./perl
BEGIN {
chdir 't' if -d 't';
@INC = '../lib';
require './test.pl'; # for which_perl() etc
}
use warnings;
plan tests => 5;
my $tmpfile = "Op_stat.tmp";
1 while unlink $tmpfile;
ok(open(F, ">", $tmpfile), 'can create temp file');
my @thwap = stat *F{IO};
ok(@thwap, "stat(*F{IO}) works");
ok( -f *F{IO} , "single file tests work with *F{IO}");
unlink $tmpfile;
ok(open(F, ">", $tmpfile), 'can create second temp file');
my @thwap2 = lstat *F{IO}; # XXX Note incorrectly using an lstat().
# Not sure just what to test for here. These tests are probably
# not right.
ok(@thwap2, "lstat(*F{IO}) works"); # Probably not right
END {
1 while unlink $tmpfile;
}
--
Andy Dougherty doughera@lafayette.edu
Thread Previous
|
Thread Next