Perl issues with opendir (or File::Find) on Windows file systems with Junction directories

Last Modified: Mon, 23 May 2011 15:18:29 +0000 ; Created: Mon, 23 May 2011 15:16:51 +0000

So I had a simple Perl script that was recursively search through directories with opendir and throwing "Invalid argument" errors on some of the child folders.

Below is some sample code:

# Tested on Windows 7
#
# Strawberry Perl
# perl 5, version 12, subversion 3 (v5.12.3) built for MSWin32-x64-multi-thread


use strict;
use warnings;


# Either style of slashes fails
#	my $junctionDir = "C:/Users/rbeede/Documents/My Pictures/";

	my $junctionDir = "C:\\Users\\rbeede\\Documents\\My Pictures";


print "$junctionDir is a symbolic link?  " . (-l $junctionDir ? 'yes' : 'no') . "\n";
print "\n";

opendir(DH, $junctionDir) || die("$!\n");

print readdir DH;

close(DH);

Turns out the issue is with Windows NTFS "junction" links. These are not real directories, but instead point to other ones. They are similar to Linux's hard links. On Windows the normal "-l pathname" can't detect these as such so it isn't easy to skip over them.

I discovered that opendir fails because by default Windows 7 has very restrictive permissions on the folder. FILE_LIST_DIRECTORY is denied to Everyone so this seems to cause Perl to just fail with "Invalid argument." I wish the Perl error would have been more descriptive. See http://dabermania.blogspot.com/2011/05/windows-7-junction-directories-why-you.html for a good explanation.

Solution:

I just chose to ignore the error since I knew the junction existed and didn't need to traverse it. If you want something that is platform dependent you could use the output from the "dir" command or possibly (untested) CPAN Win32::Symlink.