Open p5pRT opened 6 years ago
The -l file test operation is not valid to perform on a file handle\, because a file handle can't be opened on a symlink per se\, so one could never get a true result. So if we try to apply it to a file handle\, we see this warning and error result\, produced without performing any lstat:
$ strace -qqelstat perl -lwe 'print -l STDIN // "undef"' Use of -l on filehandle STDIN at -e line 1. undef
But if we try to apply it to a file handle the *other* way\, the behaviour is different:
$ strace -qqelstat perl -lwe 'print -l \*STDIN // "undef"' Use of -l on filehandle STDIN at -e line 1. lstat("GLOB(0x14bbc90)"\, 0x1495228) = -1 ENOENT (No such file or directory) undef
The warning claims that the argument is still being treated as a file handle\, but an lstat was actually performed\, using the stringification of the globref as a filename. One can even contrive for this lstat to succeed and make -l return a true result\, ostensibly on a file handle:
$ strace -qqelstat perl -lwe 'symlink "z"\, \*STDIN or die $!; print -l \*STDIN // "undef"' Use of -l on filehandle STDIN at -e line 1. lstat("GLOB(0x1bbfcc0)"\, {st_mode=S_IFLNK|0777\, st_size=1\, ...}) = 0 1
The documentation doesn't mention -l being any different in its interpretation of arguments from the other file test operators. I reckon \*STDIN should be treated consistently as a file handle\, and should yield a failure without performing any lstat syscall.
Quoth Zefram:
because a file handle can't be opened on a symlink per se
False. Darwin has the O_SYMLINK mode which lets you do exactly that. The resulting file descriptor can't be used for i/o\, but it can be passed to fstat\, fchmod\, fchown\, etc.
{ use Fcntl qw(S_ISLNK);
my $fn = "/etc/localtime"; sysopen(my $fh\, $fn\, 0x200000) or die "open: $!\n"; my @fstat = stat($fh) or die "fstat: $!\n"; close($fh); print $fn\, " is "\, S_ISLNK($fstat[2]) ? "" : "not "\, "a symlink\n"; }
/Bo Lindbergh
The RT System itself - Status changed from 'new' to 'open'
Migrated from rt.perl.org#132449 (status was 'open')
Searchable as RT132449$