Open p5pRT opened 17 years ago
Howdy All.
On Windows XP i've seen File::Find::find fail with:
Can't cd to /dir/xxx/####../../..
where the #'s are a long filename (~256 characters)
[Also note the error message does not include a separating '/' between the dir_name and ../../..'s\, or the $!]
It looks like chdir() is hitting some kind of too long pathname issue.
Here's a testcase that shows the problem:
# %\< use File::Find;
chdir '/' or die $!;
my $root_dir = '/long_dir_test';
-d $root_dir || mkdir($root_dir) || die "can't mkdir $root_dir: $!\n";
# Make a maximally length named directory # Problem seems to be filename length sensitive foreach my $dir_name ('d'\, 'di'\, 'dir') { chdir($root_dir) or die "can't chdir to $root_dir: $!\n"; while (mkdir $dir_name) { chdir $dir_name or last; } }
chdir('/') || die "can't chdir to /: $!\n";
File::Find::find(sub {}\, $root_dir); # this should die # >%
By changing the code in File::Find to do multiple individual chdir("..")'s\, it does not seem to hit the problem. The following minimal patch shows what i mean:
while ( defined ($SE = pop @Stack) ) { ($Level\, $p_dir\, $dir_rel\, $nlink) = @$SE; if ($CdLvl > $Level && !$no_chdir) { + if ($^O eq 'MSWin32') { + my $depth = $CdLvl - $Level; + while ($depth--) { + chdir("..") or die "Could not cd back to $dir_name: $!\n"; + } + } else { my $tmp; if ($Is_MacOS) { $tmp = (':' x ($CdLvl-$Level)) . ':'; @@ -939\,6 +945\,7 @@ } die "Can't cd to $dir_name" . $tmp unless chdir ($tmp); + } $CdLvl = $Level; }
I'm not sure how this affects performance - probably for the worse :-( Perhaps a better fix would use the lengths of $cwd and $dir_name to determine if multiple chdir("..")s were needed.
Cheers\, alex.
On Windows XP i've seen File::Find::find fail with:
Can't cd to /dir/####../../..
where the #'s are a long filename (~256 characters)
[Also note the error message does not include a separating '/' between the dir_name and ../../..'s\, or the value of $!\, which happens to be 'No such file or directory'.]
It looks like chdir("../../../..") is hitting some kind of too long pathname issue.
Here's a testcase that shows the problem:
# %\< use File::Find;
chdir '/' or die $!;
my $root_dir = '/long_dir_test';
-d $root_dir || mkdir($root_dir) || die "can't mkdir $root_dir: $!\n";
# Make a maximally length named directory # Problem seems to be filename length sensitive foreach my $dir_name ('d'\, 'di'\, 'dir') { chdir($root_dir) or die "can't chdir to $root_dir: $!\n"; while (mkdir $dir_name) { chdir $dir_name or last; } }
chdir('/') || die "can't chdir to /: $!\n";
File::Find::find(sub {}\, $root_dir); # this should die # >%
By changing the code in File::Find to do multiple individual chdir("..")'s\, it does not seem to hit the problem. The following minimal patch shows what i mean:
while ( defined ($SE = pop @Stack) ) { ($Level\, $p_dir\, $dir_rel\, $nlink) = @$SE; if ($CdLvl > $Level && !$no_chdir) { + if ($^O eq 'MSWin32') { + my $depth = $CdLvl - $Level; + while ($depth--) { + chdir("..") or die "Could not cd back to $dir_name: $!\n"; + } + } else { my $tmp; if ($Is_MacOS) { $tmp = (':' x ($CdLvl-$Level)) . ':'; @@ -939\,6 +945\,7 @@ } die "Can't cd to $dir_name" . $tmp unless chdir ($tmp); + } $CdLvl = $Level; }
I'm not sure how this affects performance - probably for the worse :-( It might be possible to use the value of C\< length($cwd) + length($dir_name) > to determine if multiple chdir("..")s were needed.
Cheers\, alex.
On 21/08/07\, via RT Davies\, Alex \perlbug\-followup@​perl\.org wrote:
On Windows XP i've seen File::Find::find fail with:
Can't cd to /dir/####../../..
where the #'s are a long filename (~256 characters)
[Also note the error message does not include a separating '/' between the dir_name and ../../..'s\, or the value of $!\, which happens to be 'No such file or directory'.]
It looks like chdir("../../../..") is hitting some kind of too long pathname issue.
It's probably better to fix it in chdir() instead of putting a work-around in File::Find. Can this bug be reproduced without File::Find?
The RT System itself - Status changed from 'new' to 'open'
Migrated from rt.perl.org#44819 (status was 'open')
Searchable as RT44819$