in reply to POSIX::S_ISDIR() with $stat->mode values from Windows vs. Linux

Perl's stat() emulation for Windows returns at least three different values, see Re^3: Inline.pm and untainting.

You DO NOT NEED the POSIX macro emulations and those ugly decimal notation of file modes if you just want to test if a name belongs to a directory or a plain file, use perls -X functions, especially -d to test for a directory and -f to test for a plain file.

print "$somename is a real directory" if -d($somename); print "$somename is a real plain file" if -f($somename);

Note that those function usually test the link target of a symlink, except of course for -l. If you want "real" files or directories and not symlinks, either test explicitly for a symlink or use lstat(). Think twice before insisting on "real" files or directories. Most people expect symlinks to be completely transparent for applications, so don't violate that expectation except for a very good reason (like running with root privileges in a public writeable directory like /tmp).

# way 1: explicit test print "$somename is a real directory" if !-l($somename) && -d _; print "$somename is a real plain file" if !-l($somename) && -f _; # way 2: using lstat() lstat($somename); print "$somename is a real directory" if -d _; lstat($somename); print "$somename is a real plain file" if -f _;

Note that using a single underscore as argument reuses the struct stat of the last lstat()/stat()/-X, saving slow system calls.

Update:

For the stat() return values on Windows, and the reason why stat() is emulated that way unter Windows, see Re^3: Inline.pm and untainting.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^2: POSIX::S_ISDIR() with $stat->mode values from Windows vs. Linux
by jakobi (Pilgrim) on Oct 06, 2009 at 18:25 UTC

    Alexander talked enough about symlinks that I want to add this caution on both symlinks and hardlinks to the thread:

    If you write to existing files other than append-without-backup, and there's the tiniest risk of a user trying to symlink or hardlink that file: explicitely specify how you write out the file. Funny things happen: E.g. sed -i.bak or perl i.bak and that patch on Fedora recently being removed: changing sed's semantics wrt symlinks and surprising everyone.

    date > 1; ln -s 1 2; perl -i.bak -lpe '' 2; ls -l [12]* # enjoy

    So at the very least, document how and when you're breaking symlinks or hardlinks on writing. Or not breaking them. Which might be just as bad.

    cu
    Peter

    Footnote: -d _ reuses the previous stat, as Alexander writes, just -d does a new stat using $_. So this an an example of terseness being possibly more costly in both debugging time and runtime :).