5 use warnings::register;
11 # Modified to ensure sub-directory traversal order is not inverded by stack
12 # push and pops. That is remains in the same order as in the directory file,
13 # or user pre-processing (EG:sorted).
18 File::Find - Traverse a directory tree.
23 find(\&wanted, @directories_to_search);
27 finddepth(\&wanted, @directories_to_search);
31 find({ wanted => \&process, follow => 1 }, '.');
35 These are functions for searching through directory trees doing work
36 on each file found similar to the Unix I<find> command. File::Find
37 exports two functions, C<find> and C<finddepth>. They work similarly
38 but have subtle differences.
44 find(\&wanted, @directories);
45 find(\%options, @directories);
47 C<find()> does a depth-first search over the given C<@directories> in
48 the order they are given. For each file or directory found, it calls
49 the C<&wanted> subroutine. (See below for details on how to use the
50 C<&wanted> function). Additionally, for each directory found, it will
51 C<chdir()> into that directory and continue the search, invoking the
52 C<&wanted> function on each file or subdirectory in the directory.
56 finddepth(\&wanted, @directories);
57 finddepth(\%options, @directories);
59 C<finddepth()> works just like C<find()> except that is invokes the
60 C<&wanted> function for a directory I<after> invoking it for the
61 directory's contents. It does a postorder traversal instead of a
62 preorder traversal, working from the bottom of the directory tree up
63 where C<find()> works from the top of the tree down.
69 The first argument to C<find()> is either a code reference to your
70 C<&wanted> function, or a hash reference describing the operations
71 to be performed for each file. The
72 code reference is described in L<The wanted function> below.
74 Here are the possible keys for the hash:
80 The value should be a code reference. This code reference is
81 described in L<The wanted function> below.
85 Reports the name of a directory only AFTER all its entries
86 have been reported. Entry point C<finddepth()> is a shortcut for
87 specifying C<<{ bydepth => 1 }>> in the first argument of C<find()>.
91 The value should be a code reference. This code reference is used to
92 preprocess the current directory. The name of the currently processed
93 directory is in C<$File::Find::dir>. Your preprocessing function is
94 called after C<readdir()>, but before the loop that calls the C<wanted()>
95 function. It is called with a list of strings (actually file/directory
96 names) and is expected to return a list of strings. The code can be
97 used to sort the file/directory names alphabetically, numerically,
98 or to filter out directory entries based on their name alone. When
99 I<follow> or I<follow_fast> are in effect, C<preprocess> is a no-op.
103 The value should be a code reference. It is invoked just before leaving
104 the currently processed directory. It is called in void context with no
105 arguments. The name of the current directory is in C<$File::Find::dir>. This
106 hook is handy for summarizing a directory, such as calculating its disk
107 usage. When I<follow> or I<follow_fast> are in effect, C<postprocess> is a
112 Causes symbolic links to be followed. Since directory trees with symbolic
113 links (followed) may contain files more than once and may even have
114 cycles, a hash has to be built up with an entry for each file.
115 This might be expensive both in space and time for a large
116 directory tree. See I<follow_fast> and I<follow_skip> below.
117 If either I<follow> or I<follow_fast> is in effect:
123 It is guaranteed that an I<lstat> has been called before the user's
124 C<wanted()> function is called. This enables fast file checks involving S<_>.
125 Note that this guarantee no longer holds if I<follow> or I<follow_fast>
130 There is a variable C<$File::Find::fullname> which holds the absolute
131 pathname of the file with all symbolic links resolved. If the link is
132 a dangling symbolic link, then fullname will be set to C<undef>.
136 This is a no-op on Win32.
140 This is similar to I<follow> except that it may report some files more
141 than once. It does detect cycles, however. Since only symbolic links
142 have to be hashed, this is much cheaper both in space and time. If
143 processing a file more than once (by the user's C<wanted()> function)
144 is worse than just taking time, the option I<follow> should be used.
146 This is also a no-op on Win32.
150 C<follow_skip==1>, which is the default, causes all files which are
151 neither directories nor symbolic links to be ignored if they are about
152 to be processed a second time. If a directory or a symbolic link
153 are about to be processed a second time, File::Find dies.
155 C<follow_skip==0> causes File::Find to die if any file is about to be
156 processed a second time.
158 C<follow_skip==2> causes File::Find to ignore any duplicate files and
159 directories but to proceed normally otherwise.
161 =item C<dangling_symlinks>
163 If true and a code reference, will be called with the symbolic link
164 name and the directory it lives in as arguments. Otherwise, if true
165 and warnings are on, warning "symbolic_link_name is a dangling
166 symbolic link\n" will be issued. If false, the dangling symbolic link
167 will be silently ignored.
171 Does not C<chdir()> to each directory as it recurses. The C<wanted()>
172 function will need to be aware of this, of course. In this case,
173 C<$_> will be the same as C<$File::Find::name>.
177 If find is used in taint-mode (-T command line switch or if EUID != UID
178 or if EGID != GID) then internally directory names have to be untainted
179 before they can be chdir'ed to. Therefore they are checked against a regular
180 expression I<untaint_pattern>. Note that all names passed to the user's
181 I<wanted()> function are still tainted. If this option is used while
182 not in taint-mode, C<untaint> is a no-op.
184 =item C<untaint_pattern>
186 See above. This should be set using the C<qr> quoting operator.
187 The default is set to C<qr|^([-+@\w./]+)$|>.
188 Note that the parentheses are vital.
190 =item C<untaint_skip>
192 If set, a directory which fails the I<untaint_pattern> is skipped,
193 including all its sub-directories. The default is to 'die' in such a case.
197 =head2 The wanted function
199 The C<wanted()> function does whatever verifications you want on
200 each file and directory. Note that despite its name, the C<wanted()>
201 function is a generic callback function, and does B<not> tell
202 File::Find if a file is "wanted" or not. In fact, its return value
205 The wanted function takes no arguments but rather does its work
206 through a collection of variables.
210 =item C<$File::Find::dir> is the current directory name,
212 =item C<$_> is the current filename within that directory
214 =item C<$File::Find::name> is the complete pathname to the file.
218 For example, when examining the file F</some/path/foo.ext> you will have:
220 $File::Find::dir = /some/path/
222 $File::Find::name = /some/path/foo.ext
224 You are chdir()'d to C<$File::Find::dir> when the function is called,
225 unless C<no_chdir> was specified. Note that when changing to
226 directories is in effect the root directory (F</>) is a somewhat
227 special case inasmuch as the concatenation of C<$File::Find::dir>,
228 C<'/'> and C<$_> is not literally equal to C<$File::Find::name>. The
229 table below summarizes all variants:
231 $File::Find::name $File::Find::dir $_
233 no_chdir=>0 /etc / etc
240 Do not modify these variables. If you want to use C<$_>, it must
241 be restored to its initial value before returning from the
242 function. C<local> may be used for this purpose:
245 open my $fh, '<', $_ or die "Cannot open $_ for input: $!\n";
246 local $_; # localize $_ for the remainder of the routine
250 # $_ will be restored upon leaving
253 When <follow> or <follow_fast> are in effect, there is
254 also a C<$File::Find::fullname>. The function may set
255 C<$File::Find::prune> to prune the tree unless C<bydepth> was
256 specified. Unless C<follow> or C<follow_fast> is specified, for
257 compatibility reasons (find.pl, find2perl) there are in addition the
258 following globals available: C<$File::Find::topdir>,
259 C<$File::Find::topdev>, C<$File::Find::topino>,
260 C<$File::Find::topmode> and C<$File::Find::topnlink>.
262 This library is useful for the C<find2perl> tool, which when fed,
264 find2perl / -name .nfs\* -mtime +7 \
265 -exec rm -f {} \; -o -fstype nfs -prune
267 produces something like:
271 (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)) &&
275 ($nlink || (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))) &&
277 ($File::Find::prune = 1);
280 Notice the C<_> in the above C<int(-M _)>: the C<_> is a magical
281 filehandle that caches the information from the preceding
282 C<stat()>, C<lstat()>, or filetest.
284 Here's another interesting wanted function. It will find all symbolic
285 links that don't resolve:
288 -l && !-e && print "bogus link: $File::Find::name\n";
291 See also the script C<pfind> on CPAN for a nice application of this
296 If you run your program with the C<-w> switch, or if you use the
297 C<warnings> pragma, File::Find will report warnings for several weird
298 situations. You can disable these warnings by putting the statement
300 no warnings 'File::Find';
302 in the appropriate scope. See L<perllexwarn> for more info about lexical
309 =item $dont_use_nlink
311 You can set the variable C<$File::Find::dont_use_nlink> to 1, if you want to
312 force File::Find to always stat directories. This was used for file systems
313 that do not have an C<nlink> count matching the number of sub-directories.
314 Examples are ISO-9660 (CD-ROM), AFS, HPFS (OS/2 file system), FAT (DOS file
315 system) and a couple of others.
317 You shouldn't need to set this variable, since File::Find should now detect
318 such file systems on-the-fly and switch itself to using stat. This works even
319 for parts of your file system, like a mounted CD-ROM.
321 If you do set C<$File::Find::dont_use_nlink> to 1, you will notice slow-downs.
325 Be aware that the option to follow symbolic links can be dangerous.
326 Depending on the structure of the directory tree (including symbolic
327 links to directories) you might traverse a given (physical) directory
328 more than once (only if C<follow_fast> is in effect).
329 Furthermore, deleting or changing files in a symbolically linked directory
330 might cause very unpleasant surprises, since you delete or change files
331 in an unknown directory.
341 Mac OS (Classic) users should note a few differences:
347 The path separator is ':', not '/', and the current directory is denoted
348 as ':', not '.'. You should be careful about specifying relative pathnames.
349 While a full path always begins with a volume name, a relative pathname
350 should always begin with a ':'. If specifying a volume name only, a
351 trailing ':' is required.
355 C<$File::Find::dir> is guaranteed to end with a ':'. If C<$_>
356 contains the name of a directory, that name may or may not end with a
357 ':'. Likewise, C<$File::Find::name>, which contains the complete
358 pathname to that directory, and C<$File::Find::fullname>, which holds
359 the absolute pathname of that directory with all symbolic links resolved,
360 may or may not end with a ':'.
364 The default C<untaint_pattern> (see above) on Mac OS is set to
365 C<qr|^(.+)$|>. Note that the parentheses are vital.
369 The invisible system file "Icon\015" is ignored. While this file may
370 appear in every directory, there are some more invisible system files
371 on every volume, which are all located at the volume root level (i.e.
372 "MacintoshHD:"). These system files are B<not> excluded automatically.
373 Your filter may use the following code to recognize invisible files or
374 directories (requires Mac::Files):
378 # invisible() -- returns 1 if file/directory is invisible,
379 # 0 if it's visible or undef if an error occurred
383 my ($fileCat, $fileInfo);
384 my $invisible_flag = 1 << 14;
386 if ( $fileCat = FSpGetCatInfo($file) ) {
387 if ($fileInfo = $fileCat->ioFlFndrInfo() ) {
388 return (($fileInfo->fdFlags & $invisible_flag) && 1);
394 Generally, invisible files are system files, unless an odd application
395 decides to use invisible files for its own purposes. To distinguish
396 such files from system files, you have to look at the B<type> and B<creator>
397 file attributes. The MacPerl built-in functions C<GetFileInfo(FILE)> and
398 C<SetFileInfo(CREATOR, TYPE, FILES)> offer access to these attributes
399 (see MacPerl.pm for details).
401 Files that appear on the desktop actually reside in an (hidden) directory
402 named "Desktop Folder" on the particular disk volume. Note that, although
403 all desktop files appear to be on the same "virtual" desktop, each disk
404 volume actually maintains its own "Desktop Folder" directory.
410 =head1 BUGS AND CAVEATS
412 Despite the name of the C<finddepth()> function, both C<find()> and
413 C<finddepth()> perform a depth-first search of the directory
418 File::Find used to produce incorrect results if called recursively.
419 During the development of perl 5.8 this bug was fixed.
420 The first fixed version of File::Find was 1.01.
424 our @ISA = qw(Exporter);
425 our @EXPORT = qw(find finddepth);
432 require File::Basename;
435 # Should ideally be my() not our() but local() currently
436 # refuses to operate on lexicals
439 our ($wanted_callback, $avoid_nlink, $bydepth, $no_chdir, $follow,
440 $follow_skip, $full_check, $untaint, $untaint_skip, $untaint_pat,
441 $pre_process, $post_process, $dangling_symlinks);
446 return substr($cdir,0,rindex($cdir,'/')) if $fn eq $File::Find::current_dir;
448 $cdir = substr($cdir,0,rindex($cdir,'/')+1);
452 my $abs_name= $cdir . $fn;
454 if (substr($fn,0,3) eq '../') {
455 1 while $abs_name =~ s!/[^/]*/\.\./!/!;
461 # return the absolute name of a directory or file
462 sub contract_name_Mac {
466 if ($fn =~ /^(:+)(.*)$/) { # valid pathname starting with a ':'
468 my $colon_count = length ($1);
469 if ($colon_count == 1) {
470 $abs_name = $cdir . $2;
474 # need to move up the tree, but
475 # only if it's not a volume name
476 for (my $i=1; $i<$colon_count; $i++) {
477 unless ($cdir =~ /^[^:]+:$/) { # volume name
478 $cdir =~ s/[^:]+:$//;
484 $abs_name = $cdir . $2;
491 # $fn may be a valid path to a directory or file or (dangling)
492 # symlink, without a leading ':'
493 if ( (-e $fn) || (-l $fn) ) {
494 if ($fn =~ /^[^:]+:/) { # a volume name like DataHD:*
495 return $fn; # $fn is already an absolute path
498 $abs_name = $cdir . $fn;
502 else { # argh!, $fn is not a valid directory/file
508 sub PathCombine($$) {
509 my ($Base,$Name) = @_;
513 # $Name is the resolved symlink (always a full path on MacOS),
514 # i.e. there's no need to call contract_name_Mac()
517 # (simple) check for recursion
518 if ( ( $Base =~ /^$AbsName/) && (-d $AbsName) ) { # recursion
523 if (substr($Name,0,1) eq '/') {
527 $AbsName= contract_name($Base,$Name);
530 # (simple) check for recursion
531 my $newlen= length($AbsName);
532 if ($newlen <= length($Base)) {
533 if (($newlen == length($Base) || substr($Base,$newlen,1) eq '/')
534 && $AbsName eq substr($Base,0,$newlen))
543 sub Follow_SymLink($) {
546 my ($NewName,$DEV, $INO);
547 ($DEV, $INO)= lstat $AbsName;
550 if ($SLnkSeen{$DEV, $INO}++) {
551 if ($follow_skip < 2) {
552 die "$AbsName is encountered a second time";
558 $NewName= PathCombine($AbsName, readlink($AbsName));
559 unless(defined $NewName) {
560 if ($follow_skip < 2) {
561 die "$AbsName is a recursive symbolic link";
570 ($DEV, $INO) = lstat($AbsName);
571 return undef unless defined $DEV; # dangling symbolic link
574 if ($full_check && defined $DEV && $SLnkSeen{$DEV, $INO}++) {
575 if ( ($follow_skip < 1) || ((-d _) && ($follow_skip < 2)) ) {
576 die "$AbsName encountered a second time";
586 our($dir, $name, $fullname, $prune);
587 sub _find_dir_symlnk($$$);
590 # check whether or not a scalar variable is tainted
591 # (code straight from the Camel, 3rd ed., page 561)
594 my $nada = substr($arg, 0, 0); # zero-length
596 eval { eval "# $nada" };
597 return length($@) != 0;
602 die "invalid top directory" unless defined $_[0];
604 # This function must local()ize everything because callbacks may
605 # call find() or finddepth()
608 local ($wanted_callback, $avoid_nlink, $bydepth, $no_chdir, $follow,
609 $follow_skip, $full_check, $untaint, $untaint_skip, $untaint_pat,
610 $pre_process, $post_process, $dangling_symlinks);
611 local($dir, $name, $fullname, $prune);
614 my $cwd = $wanted->{bydepth} ? Cwd::fastcwd() : Cwd::getcwd();
615 my $cwd_untainted = $cwd;
617 $wanted_callback = $wanted->{wanted};
618 $bydepth = $wanted->{bydepth};
619 $pre_process = $wanted->{preprocess};
620 $post_process = $wanted->{postprocess};
621 $no_chdir = $wanted->{no_chdir};
622 $full_check = $^O eq 'MSWin32' ? 0 : $wanted->{follow};
623 $follow = $^O eq 'MSWin32' ? 0 :
624 $full_check || $wanted->{follow_fast};
625 $follow_skip = $wanted->{follow_skip};
626 $untaint = $wanted->{untaint};
627 $untaint_pat = $wanted->{untaint_pattern};
628 $untaint_skip = $wanted->{untaint_skip};
629 $dangling_symlinks = $wanted->{dangling_symlinks};
631 # for compatibility reasons (find.pl, find2perl)
632 local our ($topdir, $topdev, $topino, $topmode, $topnlink);
634 # a symbolic link to a directory doesn't increase the link count
635 $avoid_nlink = $follow || $File::Find::dont_use_nlink;
637 my ($abs_dir, $Is_Dir);
640 foreach my $TOP (@_) {
643 ($topdev,$topino,$topmode,$topnlink) = $follow ? stat $top_item : lstat $top_item;
646 $top_item = ":$top_item"
647 if ( (-d _) && ( $top_item !~ /:/ ) );
648 } elsif ($^O eq 'MSWin32') {
649 $top_item =~ s|/\z|| unless $top_item =~ m|\w:/$|;
652 $top_item =~ s|/\z|| unless $top_item eq '/';
660 $cwd = "$cwd:" unless ($cwd =~ /:$/); # for safety
662 if ($top_item eq $File::Find::current_dir) {
666 $abs_dir = contract_name_Mac($cwd, $top_item);
667 unless (defined $abs_dir) {
668 warnings::warnif "Can't determine absolute path for $top_item (No such file or directory)\n";
675 if (substr($top_item,0,1) eq '/') {
676 $abs_dir = $top_item;
678 elsif ($top_item eq $File::Find::current_dir) {
681 else { # care about any ../
682 $abs_dir = contract_name("$cwd/",$top_item);
685 $abs_dir= Follow_SymLink($abs_dir);
686 unless (defined $abs_dir) {
687 if ($dangling_symlinks) {
688 if (ref $dangling_symlinks eq 'CODE') {
689 $dangling_symlinks->($top_item, $cwd);
691 warnings::warnif "$top_item is a dangling symbolic link\n";
698 _find_dir_symlnk($wanted, $abs_dir, $top_item);
704 unless (defined $topnlink) {
705 warnings::warnif "Can't stat $top_item: $!\n";
709 $top_item =~ s/\.dir\z//i if $Is_VMS;
710 _find_dir($wanted, $top_item, $topnlink);
719 unless (($_,$dir) = File::Basename::fileparse($abs_dir)) {
721 ($dir,$_) = (':', $top_item); # $File::Find::dir, $_
724 ($dir,$_) = ('./', $top_item);
729 if (( $untaint ) && (is_tainted($dir) )) {
730 ( $abs_dir ) = $dir =~ m|$untaint_pat|;
731 unless (defined $abs_dir) {
732 if ($untaint_skip == 0) {
733 die "directory $dir is still tainted";
741 unless ($no_chdir || chdir $abs_dir) {
742 warnings::warnif "Couldn't chdir $abs_dir: $!\n";
746 $name = $abs_dir . $_; # $File::Find::name
747 $_ = $name if $no_chdir;
749 { $wanted_callback->() }; # protect against wild "next"
753 unless ( $no_chdir ) {
754 if ( ($check_t_cwd) && (($untaint) && (is_tainted($cwd) )) ) {
755 ( $cwd_untainted ) = $cwd =~ m|$untaint_pat|;
756 unless (defined $cwd_untainted) {
757 die "insecure cwd in find(depth)";
761 unless (chdir $cwd_untainted) {
762 die "Can't cd to $cwd: $!\n";
770 # $p_dir : "parent directory"
771 # $nlink : what came back from the stat
773 # chdir (if not no_chdir) to dir
776 my ($wanted, $p_dir, $nlink) = @_;
777 my ($CdLvl,$Level) = (0,0);
780 my ($subcount,$sub_nlink);
782 my $dir_name= $p_dir;
784 my $dir_rel = $File::Find::current_dir;
789 $dir_pref= ($p_dir =~ /:$/) ? $p_dir : "$p_dir:"; # preface
790 } elsif ($^O eq 'MSWin32') {
791 $dir_pref = ($p_dir =~ m|\w:/$| ? $p_dir : "$p_dir/" );
794 $dir_pref= ( $p_dir eq '/' ? '/' : "$p_dir/" );
797 local ($dir, $name, $prune, *DIR);
799 unless ( $no_chdir || ($p_dir eq $File::Find::current_dir)) {
801 if (( $untaint ) && (is_tainted($p_dir) )) {
802 ( $udir ) = $p_dir =~ m|$untaint_pat|;
803 unless (defined $udir) {
804 if ($untaint_skip == 0) {
805 die "directory $p_dir is still tainted";
812 unless (chdir ($Is_VMS && $udir !~ /[\/\[<]+/ ? "./$udir" : $udir)) {
813 warnings::warnif "Can't cd to $udir: $!\n";
818 # push the starting directory
819 push @Stack,[$CdLvl,$p_dir,$dir_rel,-1] if $bydepth;
822 $p_dir = $dir_pref; # ensure trailing ':'
825 while (defined $SE) {
827 $dir= $p_dir; # $File::Find::dir
828 $name= $dir_name; # $File::Find::name
829 $_= ($no_chdir ? $dir_name : $dir_rel ); # $_
830 # prune may happen here
832 { $wanted_callback->() }; # protect against wild "next"
836 # change to that directory
837 unless ($no_chdir || ($dir_rel eq $File::Find::current_dir)) {
839 if ( ($untaint) && (($tainted) || ($tainted = is_tainted($dir_rel) )) ) {
840 ( $udir ) = $dir_rel =~ m|$untaint_pat|;
841 unless (defined $udir) {
842 if ($untaint_skip == 0) {
844 die "directory ($p_dir) $dir_rel is still tainted";
847 die "directory (" . ($p_dir ne '/' ? $p_dir : '') . "/) $dir_rel is still tainted";
849 } else { # $untaint_skip == 1
854 unless (chdir ($Is_VMS && $udir !~ /[\/\[<]+/ ? "./$udir" : $udir)) {
856 warnings::warnif "Can't cd to ($p_dir) $udir: $!\n";
859 warnings::warnif "Can't cd to (" .
860 ($p_dir ne '/' ? $p_dir : '') . "/) $udir: $!\n";
868 $dir_name = "$dir_name:" unless ($dir_name =~ /:$/);
871 $dir= $dir_name; # $File::Find::dir
873 # Get the list of files in the current directory.
874 unless (opendir DIR, ($no_chdir ? $dir_name : $File::Find::current_dir)) {
875 warnings::warnif "Can't opendir($dir_name): $!\n";
878 @filenames = readdir DIR;
880 @filenames = $pre_process->(@filenames) if $pre_process;
881 push @Stack,[$CdLvl,$dir_name,"",-2] if $post_process;
883 # default: use whatever was specifid
884 # (if $nlink >= 2, and $avoid_nlink == 0, this will switch back)
885 $no_nlink = $avoid_nlink;
886 # if dir has wrong nlink count, force switch to slower stat method
887 $no_nlink = 1 if ($nlink < 2);
889 if ($nlink == 2 && !$no_nlink) {
890 # This dir has no subdirectories.
891 for my $FN (@filenames) {
892 next if $FN =~ $File::Find::skip_pattern;
894 $name = $dir_pref . $FN; # $File::Find::name
895 $_ = ($no_chdir ? $name : $FN); # $_
896 { $wanted_callback->() }; # protect against wild "next"
901 # This dir has subdirectories.
902 $subcount = $nlink - 2;
904 # HACK: insert directories at this position. so as to preserve
905 # the user pre-processed ordering of files.
906 # EG: directory traversal is in user sorted order, not at random.
907 my $stack_top = @Stack;
909 for my $FN (@filenames) {
910 next if $FN =~ $File::Find::skip_pattern;
911 if ($subcount > 0 || $no_nlink) {
912 # Seen all the subdirs?
913 # check for directoriness.
914 # stat is faster for a file in the current directory
915 $sub_nlink = (lstat ($no_chdir ? $dir_pref . $FN : $FN))[3];
919 $FN =~ s/\.dir\z//i if $Is_VMS;
920 # HACK: replace push to preserve dir traversal order
921 #push @Stack,[$CdLvl,$dir_name,$FN,$sub_nlink];
922 splice @Stack, $stack_top, 0,
923 [$CdLvl,$dir_name,$FN,$sub_nlink];
926 $name = $dir_pref . $FN; # $File::Find::name
927 $_= ($no_chdir ? $name : $FN); # $_
928 { $wanted_callback->() }; # protect against wild "next"
932 $name = $dir_pref . $FN; # $File::Find::name
933 $_= ($no_chdir ? $name : $FN); # $_
934 { $wanted_callback->() }; # protect against wild "next"
940 while ( defined ($SE = pop @Stack) ) {
941 ($Level, $p_dir, $dir_rel, $nlink) = @$SE;
942 if ($CdLvl > $Level && !$no_chdir) {
945 $tmp = (':' x ($CdLvl-$Level)) . ':';
948 $tmp = join('/',('..') x ($CdLvl-$Level));
950 die "Can't cd to $dir_name" . $tmp
956 # $pdir always has a trailing ':', except for the starting dir,
957 # where $dir_rel eq ':'
958 $dir_name = "$p_dir$dir_rel";
959 $dir_pref = "$dir_name:";
961 elsif ($^O eq 'MSWin32') {
962 $dir_name = ($p_dir =~ m|\w:/$| ? "$p_dir$dir_rel" : "$p_dir/$dir_rel");
963 $dir_pref = "$dir_name/";
966 $dir_name = ($p_dir eq '/' ? "/$dir_rel" : "$p_dir/$dir_rel");
967 $dir_pref = "$dir_name/";
970 if ( $nlink == -2 ) {
971 $name = $dir = $p_dir; # $File::Find::name / dir
972 $_ = $File::Find::current_dir;
973 $post_process->(); # End-of-directory processing
975 elsif ( $nlink < 0 ) { # must be finddepth, report dirname now
978 if ($dir_rel eq ':') { # must be the top dir, where we started
979 $name =~ s|:$||; # $File::Find::name
980 $p_dir = "$p_dir:" unless ($p_dir =~ /:$/);
982 $dir = $p_dir; # $File::Find::dir
983 $_ = ($no_chdir ? $name : $dir_rel); # $_
986 if ( substr($name,-2) eq '/.' ) {
987 substr($name, length($name) == 2 ? -1 : -2) = '';
990 $_ = ($no_chdir ? $dir_name : $dir_rel );
991 if ( substr($_,-2) eq '/.' ) {
992 substr($_, length($_) == 2 ? -1 : -2) = '';
995 { $wanted_callback->() }; # protect against wild "next"
998 push @Stack,[$CdLvl,$p_dir,$dir_rel,-1] if $bydepth;
1008 # $dir_loc : absolute location of a dir
1009 # $p_dir : "parent directory"
1011 # chdir (if not no_chdir) to dir
1013 sub _find_dir_symlnk($$$) {
1014 my ($wanted, $dir_loc, $p_dir) = @_; # $dir_loc is the absolute directory
1018 my $updir_loc = $dir_loc; # untainted parent directory
1020 my $dir_name = $p_dir;
1023 my $dir_rel = $File::Find::current_dir;
1024 my $byd_flag; # flag for pending stack entry if $bydepth
1029 $dir_pref = ($p_dir =~ /:$/) ? "$p_dir" : "$p_dir:";
1030 $loc_pref = ($dir_loc =~ /:$/) ? "$dir_loc" : "$dir_loc:";
1032 $dir_pref = ( $p_dir eq '/' ? '/' : "$p_dir/" );
1033 $loc_pref = ( $dir_loc eq '/' ? '/' : "$dir_loc/" );
1036 local ($dir, $name, $fullname, $prune, *DIR);
1038 unless ($no_chdir) {
1039 # untaint the topdir
1040 if (( $untaint ) && (is_tainted($dir_loc) )) {
1041 ( $updir_loc ) = $dir_loc =~ m|$untaint_pat|; # parent dir, now untainted
1042 # once untainted, $updir_loc is pushed on the stack (as parent directory);
1043 # hence, we don't need to untaint the parent directory every time we chdir
1045 unless (defined $updir_loc) {
1046 if ($untaint_skip == 0) {
1047 die "directory $dir_loc is still tainted";
1054 $ok = chdir($updir_loc) unless ($p_dir eq $File::Find::current_dir);
1056 warnings::warnif "Can't cd to $updir_loc: $!\n";
1061 push @Stack,[$dir_loc,$updir_loc,$p_dir,$dir_rel,-1] if $bydepth;
1064 $p_dir = $dir_pref; # ensure trailing ':'
1067 while (defined $SE) {
1070 # change (back) to parent directory (always untainted)
1071 unless ($no_chdir) {
1072 unless (chdir $updir_loc) {
1073 warnings::warnif "Can't cd to $updir_loc: $!\n";
1077 $dir= $p_dir; # $File::Find::dir
1078 $name= $dir_name; # $File::Find::name
1079 $_= ($no_chdir ? $dir_name : $dir_rel ); # $_
1080 $fullname= $dir_loc; # $File::Find::fullname
1081 # prune may happen here
1083 lstat($_); # make sure file tests with '_' work
1084 { $wanted_callback->() }; # protect against wild "next"
1088 # change to that directory
1089 unless ($no_chdir || ($dir_rel eq $File::Find::current_dir)) {
1090 $updir_loc = $dir_loc;
1091 if ( ($untaint) && (($tainted) || ($tainted = is_tainted($dir_loc) )) ) {
1092 # untaint $dir_loc, what will be pushed on the stack as (untainted) parent dir
1093 ( $updir_loc ) = $dir_loc =~ m|$untaint_pat|;
1094 unless (defined $updir_loc) {
1095 if ($untaint_skip == 0) {
1096 die "directory $dir_loc is still tainted";
1103 unless (chdir $updir_loc) {
1104 warnings::warnif "Can't cd to $updir_loc: $!\n";
1110 $dir_name = "$dir_name:" unless ($dir_name =~ /:$/);
1113 $dir = $dir_name; # $File::Find::dir
1115 # Get the list of files in the current directory.
1116 unless (opendir DIR, ($no_chdir ? $dir_loc : $File::Find::current_dir)) {
1117 warnings::warnif "Can't opendir($dir_loc): $!\n";
1120 @filenames = readdir DIR;
1123 for my $FN (@filenames) {
1124 next if $FN =~ $File::Find::skip_pattern;
1126 # follow symbolic links / do an lstat
1127 $new_loc = Follow_SymLink($loc_pref.$FN);
1129 # ignore if invalid symlink
1130 unless (defined $new_loc) {
1131 if ($dangling_symlinks) {
1132 if (ref $dangling_symlinks eq 'CODE') {
1133 $dangling_symlinks->($FN, $dir_pref);
1135 warnings::warnif "$dir_pref$FN is a dangling symbolic link\n";
1140 $name = $dir_pref . $FN;
1141 $_ = ($no_chdir ? $name : $FN);
1142 { $wanted_callback->() };
1147 push @Stack,[$new_loc,$updir_loc,$dir_name,$FN,1];
1150 $fullname = $new_loc; # $File::Find::fullname
1151 $name = $dir_pref . $FN; # $File::Find::name
1152 $_ = ($no_chdir ? $name : $FN); # $_
1153 { $wanted_callback->() }; # protect against wild "next"
1159 while (defined($SE = pop @Stack)) {
1160 ($dir_loc, $updir_loc, $p_dir, $dir_rel, $byd_flag) = @$SE;
1162 # $p_dir always has a trailing ':', except for the starting dir,
1163 # where $dir_rel eq ':'
1164 $dir_name = "$p_dir$dir_rel";
1165 $dir_pref = "$dir_name:";
1166 $loc_pref = ($dir_loc =~ /:$/) ? $dir_loc : "$dir_loc:";
1169 $dir_name = ($p_dir eq '/' ? "/$dir_rel" : "$p_dir/$dir_rel");
1170 $dir_pref = "$dir_name/";
1171 $loc_pref = "$dir_loc/";
1173 if ( $byd_flag < 0 ) { # must be finddepth, report dirname now
1174 unless ($no_chdir || ($dir_rel eq $File::Find::current_dir)) {
1175 unless (chdir $updir_loc) { # $updir_loc (parent dir) is always untainted
1176 warnings::warnif "Can't cd to $updir_loc: $!\n";
1180 $fullname = $dir_loc; # $File::Find::fullname
1181 $name = $dir_name; # $File::Find::name
1183 if ($dir_rel eq ':') { # must be the top dir, where we started
1184 $name =~ s|:$||; # $File::Find::name
1185 $p_dir = "$p_dir:" unless ($p_dir =~ /:$/);
1187 $dir = $p_dir; # $File::Find::dir
1188 $_ = ($no_chdir ? $name : $dir_rel); # $_
1191 if ( substr($name,-2) eq '/.' ) {
1192 substr($name, length($name) == 2 ? -1 : -2) = ''; # $File::Find::name
1194 $dir = $p_dir; # $File::Find::dir
1195 $_ = ($no_chdir ? $dir_name : $dir_rel); # $_
1196 if ( substr($_,-2) eq '/.' ) {
1197 substr($_, length($_) == 2 ? -1 : -2) = '';
1201 lstat($_); # make sure file tests with '_' work
1202 { $wanted_callback->() }; # protect against wild "next"
1205 push @Stack,[$dir_loc, $updir_loc, $p_dir, $dir_rel,-1] if $bydepth;
1215 if ( ref($wanted) eq 'HASH' ) {
1216 if ( $wanted->{follow} || $wanted->{follow_fast}) {
1217 $wanted->{follow_skip} = 1 unless defined $wanted->{follow_skip};
1219 if ( $wanted->{untaint} ) {
1220 $wanted->{untaint_pattern} = $File::Find::untaint_pattern
1221 unless defined $wanted->{untaint_pattern};
1222 $wanted->{untaint_skip} = 0 unless defined $wanted->{untaint_skip};
1227 return { wanted => $wanted };
1233 _find_opt(wrap_wanted($wanted), @_);
1237 my $wanted = wrap_wanted(shift);
1238 $wanted->{bydepth} = 1;
1239 _find_opt($wanted, @_);
1243 $File::Find::skip_pattern = qr/^\.{1,2}\z/;
1244 $File::Find::untaint_pattern = qr|^([-+@\w./]+)$|;
1246 # These are hard-coded for now, but may move to hint files.
1249 $File::Find::dont_use_nlink = 1;
1251 elsif ($^O eq 'MacOS') {
1253 $File::Find::dont_use_nlink = 1;
1254 $File::Find::skip_pattern = qr/^Icon\015\z/;
1255 $File::Find::untaint_pattern = qr|^(.+)$|;
1258 # this _should_ work properly on all platforms
1259 # where File::Find can be expected to work
1260 $File::Find::current_dir = File::Spec->curdir || '.';
1262 $File::Find::dont_use_nlink = 1
1263 if $^O eq 'os2' || $^O eq 'dos' || $^O eq 'amigaos' || $^O eq 'MSWin32' ||
1264 $^O eq 'interix' || $^O eq 'cygwin' || $^O eq 'epoc' || $^O eq 'qnx' ||
1267 # Set dont_use_nlink in your hint file if your system's stat doesn't
1268 # report the number of links in a directory as an indication
1269 # of the number of files.
1270 # See, e.g. hints/machten.sh for MachTen 2.2.
1271 unless ($File::Find::dont_use_nlink) {
1273 $File::Find::dont_use_nlink = 1 if ($Config::Config{'dont_use_nlink'});
1276 # We need a function that checks if a scalar is tainted. Either use the
1277 # Scalar::Util module's tainted() function or our (slower) pure Perl
1278 # fallback is_tainted_pp()
1281 eval { require Scalar::Util };
1282 *is_tainted = $@ ? \&is_tainted_pp : \&Scalar::Util::tainted;