11 find - traverse a file tree
13 finddepth - traverse a directory structure depth-first
18 find(\&wanted, '/foo', '/bar');
22 finddepth(\&wanted, '/foo', '/bar');
26 find({ wanted => \&process, follow => 1 }, '.');
30 The first argument to find() is either a hash reference describing the
31 operations to be performed for each file, or a code reference.
33 Here are the possible keys for the hash:
39 The value should be a code reference. This code reference is called
40 I<the wanted() function> below.
44 Reports the name of a directory only AFTER all its entries
45 have been reported. Entry point finddepth() is a shortcut for
46 specifying C<{ bydepth => 1 }> in the first argument of find().
50 The value should be a code reference. This code reference is used to
51 preprocess the current directory. The name of currently processed
52 directory is in $File::Find::dir. Your preprocessing function is
53 called after readdir() but before the loop that calls the wanted()
54 function. It is called with a list of strings (actually file/directory
55 names) and is expected to return a list of strings. The code can be
56 used to sort the file/directory names alphabetically, numerically,
57 or to filter out directory entries based on their name alone. When
58 I<follow> or I<follow_fast> are in effect, C<preprocess> is a no-op.
62 The value should be a code reference. It is invoked just before leaving
63 the currently processed directory. It is called in void context with no
64 arguments. The name of the current directory is in $File::Find::dir. This
65 hook is handy for summarizing a directory, such as calculating its disk
66 usage. When I<follow> or I<follow_fast> are in effect, C<preprocess> is a
71 Causes symbolic links to be followed. Since directory trees with symbolic
72 links (followed) may contain files more than once and may even have
73 cycles, a hash has to be built up with an entry for each file.
74 This might be expensive both in space and time for a large
75 directory tree. See I<follow_fast> and I<follow_skip> below.
76 If either I<follow> or I<follow_fast> is in effect:
82 It is guaranteed that an I<lstat> has been called before the user's
83 I<wanted()> function is called. This enables fast file checks involving S< _>.
87 There is a variable C<$File::Find::fullname> which holds the absolute
88 pathname of the file with all symbolic links resolved
94 This is similar to I<follow> except that it may report some files more
95 than once. It does detect cycles, however. Since only symbolic links
96 have to be hashed, this is much cheaper both in space and time. If
97 processing a file more than once (by the user's I<wanted()> function)
98 is worse than just taking time, the option I<follow> should be used.
102 C<follow_skip==1>, which is the default, causes all files which are
103 neither directories nor symbolic links to be ignored if they are about
104 to be processed a second time. If a directory or a symbolic link
105 are about to be processed a second time, File::Find dies.
106 C<follow_skip==0> causes File::Find to die if any file is about to be
107 processed a second time.
108 C<follow_skip==2> causes File::Find to ignore any duplicate files and
109 directories but to proceed normally otherwise.
114 Does not C<chdir()> to each directory as it recurses. The wanted()
115 function will need to be aware of this, of course. In this case,
116 C<$_> will be the same as C<$File::Find::name>.
120 If find is used in taint-mode (-T command line switch or if EUID != UID
121 or if EGID != GID) then internally directory names have to be untainted
122 before they can be chdir'ed to. Therefore they are checked against a regular
123 expression I<untaint_pattern>. Note that all names passed to the user's
124 I<wanted()> function are still tainted. If this option is used while
125 not in taint-mode, C<untaint> is a no-op.
127 =item C<untaint_pattern>
129 See above. This should be set using the C<qr> quoting operator.
130 The default is set to C<qr|^([-+@\w./]+)$|>.
131 Note that the parantheses are vital.
133 =item C<untaint_skip>
135 If set, a directory which fails the I<untaint_pattern> is skipped,
136 including all its sub-directories. The default is to 'die' in such a case.
140 The wanted() function does whatever verifications you want.
141 C<$File::Find::dir> contains the current directory name, and C<$_> the
142 current filename within that directory. C<$File::Find::name> contains
143 the complete pathname to the file. You are chdir()'d to
144 C<$File::Find::dir> when the function is called, unless C<no_chdir>
145 was specified. When C<follow> or C<follow_fast> are in effect, there is
146 also a C<$File::Find::fullname>. The function may set
147 C<$File::Find::prune> to prune the tree unless C<bydepth> was
148 specified. Unless C<follow> or C<follow_fast> is specified, for
149 compatibility reasons (find.pl, find2perl) there are in addition the
150 following globals available: C<$File::Find::topdir>,
151 C<$File::Find::topdev>, C<$File::Find::topino>,
152 C<$File::Find::topmode> and C<$File::Find::topnlink>.
154 This library is useful for the C<find2perl> tool, which when fed,
156 find2perl / -name .nfs\* -mtime +7 \
157 -exec rm -f {} \; -o -fstype nfs -prune
159 produces something like:
163 (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)) &&
167 ($nlink || (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))) &&
169 ($File::Find::prune = 1);
172 Set the variable C<$File::Find::dont_use_nlink> if you're using AFS,
176 Here's another interesting wanted function. It will find all symlinks
180 -l && !-e && print "bogus link: $File::Find::name\n";
183 See also the script C<pfind> on CPAN for a nice application of this
188 Be aware that the option to follow symbolic links can be dangerous.
189 Depending on the structure of the directory tree (including symbolic
190 links to directories) you might traverse a given (physical) directory
191 more than once (only if C<follow_fast> is in effect).
192 Furthermore, deleting or changing files in a symbolically linked directory
193 might cause very unpleasant surprises, since you delete or change files
194 in an unknown directory.
202 Mac OS (Classic) users should note a few differences:
208 The path separator is ':', not '/', and the current directory is denoted
209 as ':', not '.'. You should be careful about specifying relative pathnames.
210 While a full path always begins with a volume name, a relative pathname
211 should always begin with a ':'. If specifying a volume name only, a
212 trailing ':' is required.
216 C<$File::Find::dir> is guaranteed to end with a ':'. If C<$_>
217 contains the name of a directory, that name may or may not end with a
218 ':'. Likewise, C<$File::Find::name>, which contains the complete
219 pathname to that directory, and C<$File::Find::fullname>, which holds
220 the absolute pathname of that directory with all symbolic links resolved,
221 may or may not end with a ':'.
225 The default C<untaint_pattern> (see above) on Mac OS is set to
226 C<qr|^(.+)$|>. Note that the parentheses are vital.
230 The invisible system file "Icon\015" is ignored. While this file may
231 appear in every directory, there are some more invisible system files
232 on every volume, which are all located at the volume root level (i.e.
233 "MacintoshHD:"). These system files are B<not> excluded automatically.
234 Your filter may use the following code to recognize invisible files or
235 directories (requires Mac::Files):
239 # invisible() -- returns 1 if file/directory is invisible,
240 # 0 if it's visible or undef if an error occured
244 my ($fileCat, $fileInfo);
245 my $invisible_flag = 1 << 14;
247 if ( $fileCat = FSpGetCatInfo($file) ) {
248 if ($fileInfo = $fileCat->ioFlFndrInfo() ) {
249 return (($fileInfo->fdFlags & $invisible_flag) && 1);
255 Generally, invisible files are system files, unless an odd application
256 decides to use invisible files for its own purposes. To distinguish
257 such files from system files, you have to look at the B<type> and B<creator>
258 file attributes. The MacPerl built-in functions C<GetFileInfo(FILE)> and
259 C<SetFileInfo(CREATOR, TYPE, FILES)> offer access to these attributes
260 (see MacPerl.pm for details).
262 Files that appear on the desktop actually reside in an (hidden) directory
263 named "Desktop Folder" on the particular disk volume. Note that, although
264 all desktop files appear to be on the same "virtual" desktop, each disk
265 volume actually maintains its own "Desktop Folder" directory.
273 File::Find used to produce incorrect results if called recursively.
274 During the development of perl 5.8 this bug was fixed.
275 The first fixed version of File::Find was 1.01.
279 our @ISA = qw(Exporter);
280 our @EXPORT = qw(find finddepth);
287 require File::Basename;
290 # Should ideally be my() not our() but local() currently
291 # refuses to operate on lexicals
294 our ($wanted_callback, $avoid_nlink, $bydepth, $no_chdir, $follow,
295 $follow_skip, $full_check, $untaint, $untaint_skip, $untaint_pat,
296 $pre_process, $post_process);
301 return substr($cdir,0,rindex($cdir,'/')) if $fn eq $File::Find::current_dir;
303 $cdir = substr($cdir,0,rindex($cdir,'/')+1);
307 my $abs_name= $cdir . $fn;
309 if (substr($fn,0,3) eq '../') {
310 1 while $abs_name =~ s!/[^/]*/\.\./!/!;
316 # return the absolute name of a directory or file
317 sub contract_name_Mac {
321 if ($fn =~ /^(:+)(.*)$/) { # valid pathname starting with a ':'
323 my $colon_count = length ($1);
324 if ($colon_count == 1) {
325 $abs_name = $cdir . $2;
329 # need to move up the tree, but
330 # only if it's not a volume name
331 for (my $i=1; $i<$colon_count; $i++) {
332 unless ($cdir =~ /^[^:]+:$/) { # volume name
333 $cdir =~ s/[^:]+:$//;
339 $abs_name = $cdir . $2;
346 # $fn may be a valid path to a directory or file or (dangling)
347 # symlink, without a leading ':'
348 if ( (-e $fn) || (-l $fn) ) {
349 if ($fn =~ /^[^:]+:/) { # a volume name like DataHD:*
350 return $fn; # $fn is already an absolute path
353 $abs_name = $cdir . $fn;
357 else { # argh!, $fn is not a valid directory/file
363 sub PathCombine($$) {
364 my ($Base,$Name) = @_;
368 # $Name is the resolved symlink (always a full path on MacOS),
369 # i.e. there's no need to call contract_name_Mac()
372 # (simple) check for recursion
373 if ( ( $Base =~ /^$AbsName/) && (-d $AbsName) ) { # recursion
378 if (substr($Name,0,1) eq '/') {
382 $AbsName= contract_name($Base,$Name);
385 # (simple) check for recursion
386 my $newlen= length($AbsName);
387 if ($newlen <= length($Base)) {
388 if (($newlen == length($Base) || substr($Base,$newlen,1) eq '/')
389 && $AbsName eq substr($Base,0,$newlen))
398 sub Follow_SymLink($) {
401 my ($NewName,$DEV, $INO);
402 ($DEV, $INO)= lstat $AbsName;
405 if ($SLnkSeen{$DEV, $INO}++) {
406 if ($follow_skip < 2) {
407 die "$AbsName is encountered a second time";
413 $NewName= PathCombine($AbsName, readlink($AbsName));
414 unless(defined $NewName) {
415 if ($follow_skip < 2) {
416 die "$AbsName is a recursive symbolic link";
425 ($DEV, $INO) = lstat($AbsName);
426 return undef unless defined $DEV; # dangling symbolic link
429 if ($full_check && $SLnkSeen{$DEV, $INO}++) {
430 if ( ($follow_skip < 1) || ((-d _) && ($follow_skip < 2)) ) {
431 die "$AbsName encountered a second time";
441 our($dir, $name, $fullname, $prune);
442 sub _find_dir_symlnk($$$);
445 # check whether or not a scalar variable is tainted
446 # (code straight from the Camel, 3rd ed., page 561)
449 my $nada = substr($arg, 0, 0); # zero-length
451 eval { eval "# $nada" };
452 return length($@) != 0;
457 die "invalid top directory" unless defined $_[0];
459 # This function must local()ize everything because callbacks may
460 # call find() or finddepth()
463 local ($wanted_callback, $avoid_nlink, $bydepth, $no_chdir, $follow,
464 $follow_skip, $full_check, $untaint, $untaint_skip, $untaint_pat,
465 $pre_process, $post_process);
466 local($dir, $name, $fullname, $prune);
468 my $cwd = $wanted->{bydepth} ? Cwd::fastcwd() : Cwd::cwd();
469 my $cwd_untainted = $cwd;
471 $wanted_callback = $wanted->{wanted};
472 $bydepth = $wanted->{bydepth};
473 $pre_process = $wanted->{preprocess};
474 $post_process = $wanted->{postprocess};
475 $no_chdir = $wanted->{no_chdir};
476 $full_check = $wanted->{follow};
477 $follow = $full_check || $wanted->{follow_fast};
478 $follow_skip = $wanted->{follow_skip};
479 $untaint = $wanted->{untaint};
480 $untaint_pat = $wanted->{untaint_pattern};
481 $untaint_skip = $wanted->{untaint_skip};
483 # for compatability reasons (find.pl, find2perl)
484 local our ($topdir, $topdev, $topino, $topmode, $topnlink);
486 # a symbolic link to a directory doesn't increase the link count
487 $avoid_nlink = $follow || $File::Find::dont_use_nlink;
489 my ($abs_dir, $Is_Dir);
492 foreach my $TOP (@_) {
496 ($topdev,$topino,$topmode,$topnlink) = $follow ? stat $top_item : lstat $top_item;
497 $top_item = ":$top_item"
498 if ( (-d _) && ($top_item =~ /^[^:]+\z/) );
501 $top_item =~ s|/\z|| unless $top_item eq '/';
502 ($topdev,$topino,$topmode,$topnlink) = $follow ? stat $top_item : lstat $top_item;
510 $cwd = "$cwd:" unless ($cwd =~ /:$/); # for safety
512 if ($top_item eq $File::Find::current_dir) {
516 $abs_dir = contract_name_Mac($cwd, $top_item);
517 unless (defined $abs_dir) {
518 warn "Can't determine absolute path for $top_item (No such file or directory)\n";
525 if (substr($top_item,0,1) eq '/') {
526 $abs_dir = $top_item;
528 elsif ($top_item eq $File::Find::current_dir) {
531 else { # care about any ../
532 $abs_dir = contract_name("$cwd/",$top_item);
535 $abs_dir= Follow_SymLink($abs_dir);
536 unless (defined $abs_dir) {
537 warn "$top_item is a dangling symbolic link\n";
542 _find_dir_symlnk($wanted, $abs_dir, $top_item);
548 unless (defined $topnlink) {
549 warn "Can't stat $top_item: $!\n";
553 $top_item =~ s/\.dir\z// if $Is_VMS;
554 _find_dir($wanted, $top_item, $topnlink);
563 unless (($_,$dir) = File::Basename::fileparse($abs_dir)) {
565 ($dir,$_) = (':', $top_item); # $File::Find::dir, $_
568 ($dir,$_) = ('./', $top_item);
573 if (( $untaint ) && (is_tainted($dir) )) {
574 ( $abs_dir ) = $dir =~ m|$untaint_pat|;
575 unless (defined $abs_dir) {
576 if ($untaint_skip == 0) {
577 die "directory $dir is still tainted";
585 unless ($no_chdir || chdir $abs_dir) {
586 warn "Couldn't chdir $abs_dir: $!\n";
590 $name = $abs_dir . $_; # $File::Find::name
592 { &$wanted_callback }; # protect against wild "next"
596 unless ( $no_chdir ) {
597 if ( ($check_t_cwd) && (($untaint) && (is_tainted($cwd) )) ) {
598 ( $cwd_untainted ) = $cwd =~ m|$untaint_pat|;
599 unless (defined $cwd_untainted) {
600 die "insecure cwd in find(depth)";
604 unless (chdir $cwd_untainted) {
605 die "Can't cd to $cwd: $!\n";
613 # $p_dir : "parent directory"
614 # $nlink : what came back from the stat
616 # chdir (if not no_chdir) to dir
619 my ($wanted, $p_dir, $nlink) = @_;
620 my ($CdLvl,$Level) = (0,0);
623 my ($subcount,$sub_nlink);
625 my $dir_name= $p_dir;
631 $dir_pref= ($p_dir =~ /:$/) ? $p_dir : "$p_dir:"; # preface
632 $dir_rel= ':'; # directory name relative to current directory
635 $dir_pref= ( $p_dir eq '/' ? '/' : "$p_dir/" );
636 $dir_rel= '.'; # directory name relative to current directory
639 local ($dir, $name, $prune, *DIR);
641 unless ( $no_chdir || ($p_dir eq $File::Find::current_dir)) {
643 if (( $untaint ) && (is_tainted($p_dir) )) {
644 ( $udir ) = $p_dir =~ m|$untaint_pat|;
645 unless (defined $udir) {
646 if ($untaint_skip == 0) {
647 die "directory $p_dir is still tainted";
654 unless (chdir $udir) {
655 warn "Can't cd to $udir: $!\n";
660 # push the starting directory
661 push @Stack,[$CdLvl,$p_dir,$dir_rel,-1] if $bydepth;
664 $p_dir = $dir_pref; # ensure trailing ':'
667 while (defined $SE) {
669 $dir= $p_dir; # $File::Find::dir
670 $name= $dir_name; # $File::Find::name
671 $_= ($no_chdir ? $dir_name : $dir_rel ); # $_
672 # prune may happen here
674 { &$wanted_callback }; # protect against wild "next"
678 # change to that directory
679 unless ($no_chdir || ($dir_rel eq $File::Find::current_dir)) {
681 if ( ($untaint) && (($tainted) || ($tainted = is_tainted($dir_rel) )) ) {
682 ( $udir ) = $dir_rel =~ m|$untaint_pat|;
683 unless (defined $udir) {
684 if ($untaint_skip == 0) {
686 die "directory ($p_dir) $dir_rel is still tainted";
689 die "directory (" . ($p_dir ne '/' ? $p_dir : '') . "/) $dir_rel is still tainted";
691 } else { # $untaint_skip == 1
696 unless (chdir $udir) {
698 warn "Can't cd to ($p_dir) $udir: $!\n";
701 warn "Can't cd to (" . ($p_dir ne '/' ? $p_dir : '') . "/) $udir: $!\n";
709 $dir_name = "$dir_name:" unless ($dir_name =~ /:$/);
712 $dir= $dir_name; # $File::Find::dir
714 # Get the list of files in the current directory.
715 unless (opendir DIR, ($no_chdir ? $dir_name : $File::Find::current_dir)) {
716 warn "Can't opendir($dir_name): $!\n";
719 @filenames = readdir DIR;
721 @filenames = &$pre_process(@filenames) if $pre_process;
722 push @Stack,[$CdLvl,$dir_name,"",-2] if $post_process;
724 if ($nlink == 2 && !$avoid_nlink) {
725 # This dir has no subdirectories.
726 for my $FN (@filenames) {
727 next if $FN =~ $File::Find::skip_pattern;
729 $name = $dir_pref . $FN; # $File::Find::name
730 $_ = ($no_chdir ? $name : $FN); # $_
731 { &$wanted_callback }; # protect against wild "next"
736 # This dir has subdirectories.
737 $subcount = $nlink - 2;
739 for my $FN (@filenames) {
740 next if $FN =~ $File::Find::skip_pattern;
741 if ($subcount > 0 || $avoid_nlink) {
742 # Seen all the subdirs?
743 # check for directoriness.
744 # stat is faster for a file in the current directory
745 $sub_nlink = (lstat ($no_chdir ? $dir_pref . $FN : $FN))[3];
749 $FN =~ s/\.dir\z// if $Is_VMS;
750 push @Stack,[$CdLvl,$dir_name,$FN,$sub_nlink];
753 $name = $dir_pref . $FN; # $File::Find::name
754 $_= ($no_chdir ? $name : $FN); # $_
755 { &$wanted_callback }; # protect against wild "next"
759 $name = $dir_pref . $FN; # $File::Find::name
760 $_= ($no_chdir ? $name : $FN); # $_
761 { &$wanted_callback }; # protect against wild "next"
767 while ( defined ($SE = pop @Stack) ) {
768 ($Level, $p_dir, $dir_rel, $nlink) = @$SE;
769 if ($CdLvl > $Level && !$no_chdir) {
772 $tmp = (':' x ($CdLvl-$Level)) . ':';
775 $tmp = join('/',('..') x ($CdLvl-$Level));
777 die "Can't cd to $dir_name" . $tmp
783 # $pdir always has a trailing ':', except for the starting dir,
784 # where $dir_rel eq ':'
785 $dir_name = "$p_dir$dir_rel";
786 $dir_pref = "$dir_name:";
789 $dir_name = ($p_dir eq '/' ? "/$dir_rel" : "$p_dir/$dir_rel");
790 $dir_pref = "$dir_name/";
793 if ( $nlink == -2 ) {
794 $name = $dir = $p_dir; # $File::Find::name / dir
801 &$post_process; # End-of-directory processing
803 elsif ( $nlink < 0 ) { # must be finddepth, report dirname now
806 if ($dir_rel eq ':') { # must be the top dir, where we started
807 $name =~ s|:$||; # $File::Find::name
808 $p_dir = "$p_dir:" unless ($p_dir =~ /:$/);
810 $dir = $p_dir; # $File::Find::dir
811 $_ = ($no_chdir ? $name : $dir_rel); # $_
814 if ( substr($name,-2) eq '/.' ) {
818 $_ = ($no_chdir ? $dir_name : $dir_rel );
819 if ( substr($_,-2) eq '/.' ) {
823 { &$wanted_callback }; # protect against wild "next"
826 push @Stack,[$CdLvl,$p_dir,$dir_rel,-1] if $bydepth;
836 # $dir_loc : absolute location of a dir
837 # $p_dir : "parent directory"
839 # chdir (if not no_chdir) to dir
841 sub _find_dir_symlnk($$$) {
842 my ($wanted, $dir_loc, $p_dir) = @_; # $dir_loc is the absolute directory
846 my $updir_loc = $dir_loc; # untainted parent directory
848 my $dir_name = $p_dir;
852 my $byd_flag; # flag for pending stack entry if $bydepth
857 $dir_pref = ($p_dir =~ /:$/) ? "$p_dir" : "$p_dir:";
858 $loc_pref = ($dir_loc =~ /:$/) ? "$dir_loc" : "$dir_loc:";
859 $dir_rel = ':'; # directory name relative to current directory
861 $dir_pref = ( $p_dir eq '/' ? '/' : "$p_dir/" );
862 $loc_pref = ( $dir_loc eq '/' ? '/' : "$dir_loc/" );
863 $dir_rel = '.'; # directory name relative to current directory
866 local ($dir, $name, $fullname, $prune, *DIR);
870 if (( $untaint ) && (is_tainted($dir_loc) )) {
871 ( $updir_loc ) = $dir_loc =~ m|$untaint_pat|; # parent dir, now untainted
872 # once untainted, $updir_loc is pushed on the stack (as parent directory);
873 # hence, we don't need to untaint the parent directory every time we chdir
875 unless (defined $updir_loc) {
876 if ($untaint_skip == 0) {
877 die "directory $dir_loc is still tainted";
884 $ok = chdir($updir_loc) unless ($p_dir eq $File::Find::current_dir);
886 warn "Can't cd to $updir_loc: $!\n";
891 push @Stack,[$dir_loc,$updir_loc,$p_dir,$dir_rel,-1] if $bydepth;
894 $p_dir = $dir_pref; # ensure trailing ':'
897 while (defined $SE) {
900 # change (back) to parent directory (always untainted)
902 unless (chdir $updir_loc) {
903 warn "Can't cd to $updir_loc: $!\n";
907 $dir= $p_dir; # $File::Find::dir
908 $name= $dir_name; # $File::Find::name
909 $_= ($no_chdir ? $dir_name : $dir_rel ); # $_
910 $fullname= $dir_loc; # $File::Find::fullname
911 # prune may happen here
913 lstat($_); # make sure file tests with '_' work
914 { &$wanted_callback }; # protect against wild "next"
918 # change to that directory
919 unless ($no_chdir || ($dir_rel eq $File::Find::current_dir)) {
920 $updir_loc = $dir_loc;
921 if ( ($untaint) && (($tainted) || ($tainted = is_tainted($dir_loc) )) ) {
922 # untaint $dir_loc, what will be pushed on the stack as (untainted) parent dir
923 ( $updir_loc ) = $dir_loc =~ m|$untaint_pat|;
924 unless (defined $updir_loc) {
925 if ($untaint_skip == 0) {
926 die "directory $dir_loc is still tainted";
933 unless (chdir $updir_loc) {
934 warn "Can't cd to $updir_loc: $!\n";
940 $dir_name = "$dir_name:" unless ($dir_name =~ /:$/);
943 $dir = $dir_name; # $File::Find::dir
945 # Get the list of files in the current directory.
946 unless (opendir DIR, ($no_chdir ? $dir_loc : $File::Find::current_dir)) {
947 warn "Can't opendir($dir_loc): $!\n";
950 @filenames = readdir DIR;
953 for my $FN (@filenames) {
954 next if $FN =~ $File::Find::skip_pattern;
956 # follow symbolic links / do an lstat
957 $new_loc = Follow_SymLink($loc_pref.$FN);
959 # ignore if invalid symlink
960 next unless defined $new_loc;
963 push @Stack,[$new_loc,$updir_loc,$dir_name,$FN,1];
966 $fullname = $new_loc; # $File::Find::fullname
967 $name = $dir_pref . $FN; # $File::Find::name
968 $_ = ($no_chdir ? $name : $FN); # $_
969 { &$wanted_callback }; # protect against wild "next"
975 while (defined($SE = pop @Stack)) {
976 ($dir_loc, $updir_loc, $p_dir, $dir_rel, $byd_flag) = @$SE;
978 # $p_dir always has a trailing ':', except for the starting dir,
979 # where $dir_rel eq ':'
980 $dir_name = "$p_dir$dir_rel";
981 $dir_pref = "$dir_name:";
982 $loc_pref = ($dir_loc =~ /:$/) ? $dir_loc : "$dir_loc:";
985 $dir_name = ($p_dir eq '/' ? "/$dir_rel" : "$p_dir/$dir_rel");
986 $dir_pref = "$dir_name/";
987 $loc_pref = "$dir_loc/";
989 if ( $byd_flag < 0 ) { # must be finddepth, report dirname now
990 unless ($no_chdir || ($dir_rel eq $File::Find::current_dir)) {
991 unless (chdir $updir_loc) { # $updir_loc (parent dir) is always untainted
992 warn "Can't cd to $updir_loc: $!\n";
996 $fullname = $dir_loc; # $File::Find::fullname
997 $name = $dir_name; # $File::Find::name
999 if ($dir_rel eq ':') { # must be the top dir, where we started
1000 $name =~ s|:$||; # $File::Find::name
1001 $p_dir = "$p_dir:" unless ($p_dir =~ /:$/);
1003 $dir = $p_dir; # $File::Find::dir
1004 $_ = ($no_chdir ? $name : $dir_rel); # $_
1007 if ( substr($name,-2) eq '/.' ) {
1008 $name =~ s|/\.$||; # $File::Find::name
1010 $dir = $p_dir; # $File::Find::dir
1011 $_ = ($no_chdir ? $dir_name : $dir_rel); # $_
1012 if ( substr($_,-2) eq '/.' ) {
1017 lstat($_); # make sure file tests with '_' work
1018 { &$wanted_callback }; # protect against wild "next"
1021 push @Stack,[$dir_loc, $updir_loc, $p_dir, $dir_rel,-1] if $bydepth;
1031 if ( ref($wanted) eq 'HASH' ) {
1032 if ( $wanted->{follow} || $wanted->{follow_fast}) {
1033 $wanted->{follow_skip} = 1 unless defined $wanted->{follow_skip};
1035 if ( $wanted->{untaint} ) {
1036 $wanted->{untaint_pattern} = $File::Find::untaint_pattern
1037 unless defined $wanted->{untaint_pattern};
1038 $wanted->{untaint_skip} = 0 unless defined $wanted->{untaint_skip};
1043 return { wanted => $wanted };
1049 _find_opt(wrap_wanted($wanted), @_);
1053 my $wanted = wrap_wanted(shift);
1054 $wanted->{bydepth} = 1;
1055 _find_opt($wanted, @_);
1059 $File::Find::skip_pattern = qr/^\.{1,2}\z/;
1060 $File::Find::untaint_pattern = qr|^([-+@\w./]+)$|;
1062 # These are hard-coded for now, but may move to hint files.
1065 $File::Find::dont_use_nlink = 1;
1067 elsif ($^O eq 'MacOS') {
1069 $File::Find::dont_use_nlink = 1;
1070 $File::Find::skip_pattern = qr/^Icon\015\z/;
1071 $File::Find::untaint_pattern = qr|^(.+)$|;
1074 # this _should_ work properly on all platforms
1075 # where File::Find can be expected to work
1076 $File::Find::current_dir = File::Spec->curdir || '.';
1078 $File::Find::dont_use_nlink = 1
1079 if $^O eq 'os2' || $^O eq 'dos' || $^O eq 'amigaos' || $^O eq 'MSWin32' ||
1080 $^O eq 'cygwin' || $^O eq 'epoc';
1082 # Set dont_use_nlink in your hint file if your system's stat doesn't
1083 # report the number of links in a directory as an indication
1084 # of the number of files.
1085 # See, e.g. hints/machten.sh for MachTen 2.2.
1086 unless ($File::Find::dont_use_nlink) {
1088 $File::Find::dont_use_nlink = 1 if ($Config::Config{'dont_use_nlink'});
1091 # We need a function that checks if a scalar is tainted. Either use the
1092 # Scalar::Util module's tainted() function or our (slower) pure Perl
1093 # fallback is_tainted_pp()
1096 eval { require Scalar::Util };
1097 *is_tainted = $@ ? \&is_tainted_pp : \&Scalar::Util::tainted;