diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-09-17 20:16:36 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-09-17 20:16:36 -0700 |
commit | 1f26655e82dbc83bdd3dbbc6003d6099c44c2982 (patch) | |
tree | f3903b49e415dca90d85c54b53e63b13391fc156 /t/op/filetest.t | |
parent | 962c024be0fcb06afec58a17b65e73fc0d0f9214 (diff) | |
download | perl-1f26655e82dbc83bdd3dbbc6003d6099c44c2982.tar.gz |
Make stacked -l work
Perl 5.10.0 introduced stacked filetest operators,
-x -r $foo
being equivalent to
-r $foo && -x _
That does not work with -l. It was these suspicious lines in
Perl_my_lstat_flags that drew my attention to it:
> else if (PL_laststype != OP_LSTAT
> && (PL_op->op_private & OPpFT_STACKED) && ckWARN(WARN_IO))
> Perl_croak(aTHX_ no_prev_lstat);
That croak only happens when warnings are on. Warnings are just
supposed to be warnings, unless the ‘user’ explicitly requests
fatal warnings.
$ perl -le 'print "foo", -l -e "miniperl"'
foo
$ perl -lwe 'print "foo", -l -e "miniperl"'
The stat preceding -l _ wasn't an lstat at -e line 1.
That it doesn’t die in the first example is a bug.
In fact, it’s using the return value of -e as a file name:
$ ln -s miniperl 1
$ ./miniperl -le 'print -l -e "miniperl"'
1
And, with warnings on, if the preceding stat *was* an lstat, it
falls back to the pre-stacked behaviour, just as it does when warn-
ings are off.
It’s meant to be equivalent to -e "miniperl" && -l _ (which is why the
error message above says ‘The stat preceding -l _’).
Diffstat (limited to 't/op/filetest.t')
-rw-r--r-- | t/op/filetest.t | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/t/op/filetest.t b/t/op/filetest.t index 08380d1c97..3b09c2b10c 100644 --- a/t/op/filetest.t +++ b/t/op/filetest.t @@ -10,7 +10,7 @@ BEGIN { } use Config; -plan(tests => 30 + 27*14); +plan(tests => 33 + 27*14); ok( -d 'op' ); ok( -f 'TEST' ); @@ -89,6 +89,29 @@ is( -f -s $tempfile, 0 ); is( -s -f $tempfile, 0 ); unlink_all $tempfile; +# stacked -l +eval { -l -e "TEST" }; +like $@, qr/^The stat preceding -l _ wasn't an lstat at /, + 'stacked -l non-lstat error with warnings off'; +{ + local $^W = 1; + eval { -l -e "TEST" }; + like $@, qr/^The stat preceding -l _ wasn't an lstat at /, + 'stacked -l non-lstat error with warnings on'; +} +# Make sure -l is using the previous stat buffer, and not using the previ- +# ous op’s return value as a file name. +SKIP: { + use Perl::OSType 'os_type'; + if (os_type ne 'Unix') { skip "Not Unix", 1 } + chomp(my $ln = `which ln`); + if ( ! -e $ln ) { skip "No ln" , 1 } + lstat "TEST"; + `ln -s TEST 1`; + ok ! -l -e _, 'stacked -l uses previous stat, not previous retval'; + unlink 1; +} + # test that _ is a bareword after filetest operators -f 'TEST'; |