From: Gurusamy Sarathy <gsar@cpan.org>
Date: Tue, 29 Feb 2000 23:02:34 +0000 (+0000)
Subject: fix File::Find::finddepth() bugs (from Helmut Jarausch)
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=57e73c4b0ab7f637f07667e3f6fda277d0671dc3;p=p5sagit%2Fp5-mst-13.2.git

fix File::Find::finddepth() bugs (from Helmut Jarausch)

p4raw-id: //depot/perl@5375
---

diff --git a/lib/File/Find.pm b/lib/File/Find.pm
index 074cff3..71cc0e6 100644
--- a/lib/File/Find.pm
+++ b/lib/File/Find.pm
@@ -419,6 +419,8 @@ sub _find_dir($$$) {
 	    return;
 	}
     }
+    
+    push @Stack,[$CdLvl,$p_dir,$dir_rel,-1]  if  $bydepth;
 
     while (defined $SE) {
 	unless ($bydepth) {
@@ -504,15 +506,9 @@ sub _find_dir($$$) {
 		}
 	    }
 	}
-	if ($bydepth) {
-            $name = $dir_name;
-            $dir = $p_dir;
-            $_ = ($no_chdir ? $dir_name : $dir_rel );
-            &$wanted_callback;
-	}
     }
     continue {
-	if ( defined ($SE = pop @Stack) ) {
+	while ( defined ($SE = pop @Stack) ) {
 	    ($Level, $p_dir, $dir_rel, $nlink) = @$SE;
 	    if ($CdLvl > $Level && !$no_chdir) {
 		die "Can't cd to $dir_name" . '../' x ($CdLvl-$Level)
@@ -521,6 +517,15 @@ sub _find_dir($$$) {
 	    }
 	    $dir_name = ($p_dir eq '/' ? "/$dir_rel" : "$p_dir/$dir_rel");
 	    $dir_pref = "$dir_name/";
+            if ( $nlink < 0 ) {  # must be finddepth, report dirname now
+                $name = $dir_name;
+                $dir = $p_dir;
+                $_ = ($no_chdir ? $dir_name : $dir_rel );
+                &$wanted_callback;
+            } else {
+                push @Stack,[$CdLvl,$p_dir,$dir_rel,-1]  if  $bydepth;
+                last;
+            }
 	}
     }
 }
@@ -538,11 +543,13 @@ sub _find_dir_symlnk($$$) {
     my @Stack;
     my @filenames;
     my $new_loc;
+    my $pdir_loc = $dir_loc;
     my $SE = [];
     my $dir_name = $p_dir;
     my $dir_pref = ( $p_dir   eq '/' ? '/' : "$p_dir/" );
     my $loc_pref = ( $dir_loc eq '/' ? '/' : "$dir_loc/" );
     my $dir_rel = '.';		# directory name relative to current directory
+    my $byd_flag;               # flag for pending stack entry if $bydepth
 
     local ($dir, $name, $fullname, $prune, *DIR);
     
@@ -565,6 +572,8 @@ sub _find_dir_symlnk($$$) {
 	}
     }
 
+    push @Stack,[$dir_loc,$pdir_loc,$p_dir,$dir_rel,-1]  if  $bydepth;
+
     while (defined $SE) {
 
 	unless ($bydepth) {
@@ -618,7 +627,7 @@ sub _find_dir_symlnk($$$) {
 	    next unless defined $new_loc;
      
 	    if (-d _) {
-		push @Stack,[$new_loc,$dir_name,$FN];
+		push @Stack,[$new_loc,$dir_loc,$dir_name,$FN,1];
 	    }
 	    else {
 		$fullname = $new_loc;
@@ -628,19 +637,33 @@ sub _find_dir_symlnk($$$) {
 	    }
 	}
 
-	if ($bydepth) {
-	    $fullname = $dir_loc;
-	    $name = $dir_name;
-	    $_ = ($no_chdir ? $dir_name : $dir_rel);
-	    &$wanted_callback;
-	}
     }
     continue {
-	if (defined($SE = pop @Stack)) {
-	    ($dir_loc, $p_dir, $dir_rel) = @$SE;
+	while (defined($SE = pop @Stack)) {
+	    ($dir_loc, $pdir_loc, $p_dir, $dir_rel, $byd_flag) = @$SE;
 	    $dir_name = ($p_dir eq '/' ? "/$dir_rel" : "$p_dir/$dir_rel");
 	    $dir_pref = "$dir_name/";
 	    $loc_pref = "$dir_loc/";
+            if ( $byd_flag < 0 ) {  # must be finddepth, report dirname now
+	        unless ($no_chdir or $dir_rel eq '.') {
+	            my $udir = $pdir_loc;
+	            if ($untaint) {
+		        $udir = $1 if $dir_loc =~ m|$untaint_pat|;
+	            }
+	            unless (chdir $udir) {
+		        warn "Can't cd to $udir: $!\n";
+		        next;
+	            }
+	        }
+	        $fullname = $dir_loc;
+	        $name = $dir_name;
+                $dir = $p_dir;
+	        $_ = ($no_chdir ? $dir_name : $dir_rel);
+	        &$wanted_callback;
+            } else {
+                push @Stack,[$dir_loc, $pdir_loc, $p_dir, $dir_rel,-1]  if  $bydepth;
+                last;
+            }
 	}
     }
 }