1 /* find -- search for files in a directory hierarchy
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2004 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 /* GNU find was written by Eric Decker <cire@cisco.com>,
20 with enhancements by David MacKenzie <djm@gnu.ai.mit.edu>,
21 Jay Plett <jay@silence.princeton.nj.us>,
22 and Tim Wood <axolotl!tim@toad.com>.
23 The idea for -print0 and xargs -0 came from
24 Dan Bernstein <brnstnd@kramden.acf.nyu.edu>. */
28 #define USE_SAFE_CHDIR 1
39 #include "../gnulib/lib/xalloc.h"
40 #include "../gnulib/lib/human.h"
41 #include "../gnulib/lib/canonicalize.h"
43 #include "../gnulib/lib/savedir.h"
51 # define _(Text) gettext (Text)
54 #define textdomain(Domain)
55 #define bindtextdomain(Package, Directory)
58 # define N_(String) gettext_noop (String)
60 /* See locate.c for explanation as to why not use (String) */
61 # define N_(String) String
64 #define apply_predicate(pathname, stat_buf_ptr, node) \
65 (*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
68 static void init_mounted_dev_list(void);
69 static void process_top_path
PARAMS((char *pathname
));
70 static int process_path
PARAMS((char *pathname
, char *name
, boolean leaf
, char *parent
));
71 static void process_dir
PARAMS((char *pathname
, char *name
, int pathlen
, struct stat
*statp
, char *parent
));
75 static boolean default_prints
PARAMS((struct predicate
*pred
));
77 /* Name this program was run with. */
80 /* All predicates for each path to process. */
81 struct predicate
*predicates
;
83 /* The last predicate allocated. */
84 struct predicate
*last_pred
;
86 /* The root of the evaluation tree. */
87 static struct predicate
*eval_tree
;
90 struct options options
;
93 /* The full path of the initial working directory, or "." if
94 STARTING_DESC is nonnegative. */
95 char const *starting_dir
= ".";
97 /* A file descriptor open to the initial working directory.
98 Doing it this way allows us to work when the i.w.d. has
99 unreadable parents. */
102 /* The stat buffer of the initial working directory. */
103 struct stat starting_stat_buf
;
106 enum TraversalDirection
114 following_links(void)
116 switch (options
.symlink_handling
)
118 case SYMLINK_ALWAYS_DEREF
:
120 case SYMLINK_DEREF_ARGSONLY
:
121 return (state
.curdepth
== 0);
122 case SYMLINK_NEVER_DEREF
:
130 fallback_stat(const char *name
, struct stat
*p
, int prev_rv
)
132 /* Our original stat() call failed. Perhaps we can't follow a
133 * symbolic link. If that might be the problem, lstat() the link.
134 * Otherwise, admit defeat.
141 fprintf(stderr
, "fallback_stat(): stat(%s) failed; falling back on lstat()\n", name
);
143 return lstat(name
, p
);
150 case EOVERFLOW
: /* EOVERFLOW is not #defined on UNICOS. */
158 /* optionh_stat() implements the stat operation when the -H option is
161 * If the item to be examined is a command-line argument, we follow
162 * symbolic links. If the stat() call fails on the command-line item,
163 * we fall back on the properties of the symbolic link.
165 * If the item to be examined is not a command-line argument, we
166 * examine the link itself.
169 optionh_stat(const char *name
, struct stat
*p
)
171 if (0 == state
.curdepth
)
173 /* This file is from the command line; deference the link (if it
176 int rv
= stat(name
, p
);
178 return 0; /* success */
180 return fallback_stat(name
, p
, rv
);
184 /* Not a file on the command line; do not derefernce the link.
186 return lstat(name
, p
);
190 /* optionl_stat() implements the stat operation when the -L option is
191 * in effect. That option makes us examine the thing the symbolic
192 * link points to, not the symbolic link itself.
195 optionl_stat(const char *name
, struct stat
*p
)
197 int rv
= stat(name
, p
);
199 return 0; /* normal case. */
201 return fallback_stat(name
, p
, rv
);
204 /* optionp_stat() implements the stat operation when the -P option is
205 * in effect (this is also the default). That option makes us examine
206 * the symbolic link itself, not the thing it points to.
209 optionp_stat(const char *name
, struct stat
*p
)
211 return lstat(name
, p
);
215 static uintmax_t stat_count
= 0u;
218 debug_stat (const char *file
, struct stat
*bufp
)
221 fprintf (stderr
, "debug_stat (%s)\n", file
);
222 switch (options
.symlink_handling
)
224 case SYMLINK_ALWAYS_DEREF
:
225 return optionl_stat(file
, bufp
);
226 case SYMLINK_DEREF_ARGSONLY
:
227 return optionh_stat(file
, bufp
);
228 case SYMLINK_NEVER_DEREF
:
229 return optionp_stat(file
, bufp
);
232 #endif /* DEBUG_STAT */
235 set_follow_state(enum SymlinkOption opt
)
239 case SYMLINK_ALWAYS_DEREF
: /* -L */
240 options
.xstat
= optionl_stat
;
241 options
.no_leaf_check
= true;
244 case SYMLINK_NEVER_DEREF
: /* -P (default) */
245 options
.xstat
= optionp_stat
;
246 /* Can't turn no_leaf_check off because the user might have specified
251 case SYMLINK_DEREF_ARGSONLY
: /* -H */
252 options
.xstat
= optionh_stat
;
253 options
.no_leaf_check
= true;
256 options
.symlink_handling
= opt
;
258 /* For DBEUG_STAT, the choice is made at runtime within debug_stat()
259 * by checking the contents of the symlink_handling variable.
261 #if defined(DEBUG_STAT)
262 options
.xstat
= debug_stat
;
263 #endif /* !DEBUG_STAT */
268 main (int argc
, char **argv
)
271 PFB parse_function
; /* Pointer to the function which parses. */
272 struct predicate
*cur_pred
;
273 char *predicate_name
; /* Name of predicate being parsed. */
274 int end_of_leading_options
= 0; /* First arg after any -H/-L etc. */
275 program_name
= argv
[0];
277 #ifdef HAVE_SETLOCALE
278 setlocale (LC_ALL
, "");
280 bindtextdomain (PACKAGE
, LOCALEDIR
);
281 textdomain (PACKAGE
);
285 options
.warnings
= true;
289 options
.warnings
= false;
295 options
.do_dir_first
= true;
296 options
.maxdepth
= options
.mindepth
= -1;
297 options
.start_time
= time (NULL
);
298 options
.cur_day_start
= options
.start_time
- DAYSECS
;
299 options
.full_days
= false;
300 options
.stay_on_filesystem
= false;
301 options
.ignore_readdir_race
= false;
303 state
.exit_status
= 0;
305 #if defined(DEBUG_STAT)
306 options
.xstat
= debug_stat
;
307 #endif /* !DEBUG_STAT */
309 if (getenv("POSIXLY_CORRECT"))
310 options
.output_block_size
= 512;
312 options
.output_block_size
= 1024;
314 if (getenv("FIND_BLOCK_SIZE"))
316 error (1, 0, _("The environment variable FIND_BLOCK_SIZE is not supported, the only thing that affects the block size is the POSIXLY_CORRECT environment variable"));
319 options
.no_leaf_check
= false;
320 set_follow_state(SYMLINK_NEVER_DEREF
); /* The default is equivalent to -P. */
322 init_mounted_dev_list();
325 fprintf (stderr
, "cur_day_start = %s", ctime (&options
.cur_day_start
));
328 /* Check for -P, -H or -L options. */
329 for (i
=1; (end_of_leading_options
= i
) < argc
; ++i
)
331 if (0 == strcmp("-H", argv
[i
]))
333 /* Meaning: dereference symbolic links on command line, but nowhere else. */
334 set_follow_state(SYMLINK_DEREF_ARGSONLY
);
336 else if (0 == strcmp("-L", argv
[i
]))
338 /* Meaning: dereference all symbolic links. */
339 set_follow_state(SYMLINK_ALWAYS_DEREF
);
341 else if (0 == strcmp("-P", argv
[i
]))
343 /* Meaning: never dereference symbolic links (default). */
344 set_follow_state(SYMLINK_NEVER_DEREF
);
346 else if (0 == strcmp("--", argv
[i
]))
348 /* -- signifies the end of options. */
349 end_of_leading_options
= i
+1; /* Next time start with the next option */
354 /* Hmm, must be one of
358 end_of_leading_options
= i
; /* Next time start with this option */
363 /* We are now processing the part of the "find" command line
364 * after the -H/-L options (if any).
367 /* fprintf(stderr, "rest: optind=%ld\n", (long)optind); */
369 /* Find where in ARGV the predicates begin. */
370 for (i
= end_of_leading_options
; i
< argc
&& strchr ("-!(),", argv
[i
][0]) == NULL
; i
++)
372 /* fprintf(stderr, "Looks like %s is not a predicate\n", argv[i]); */
376 /* Enclose the expression in `( ... )' so a default -print will
377 apply to the whole expression. */
378 parse_open (argv
, &argc
);
379 /* Build the input order list. */
382 if (strchr ("-!(),", argv
[i
][0]) == NULL
)
383 usage (_("paths must precede expression"));
384 predicate_name
= argv
[i
];
385 parse_function
= find_parser (predicate_name
);
386 if (parse_function
== NULL
)
387 /* Command line option not recognized */
388 error (1, 0, _("invalid predicate `%s'"), predicate_name
);
390 if (!(*parse_function
) (argv
, &i
))
393 /* Command line option requires an argument */
394 error (1, 0, _("missing argument to `%s'"), predicate_name
);
396 error (1, 0, _("invalid argument `%s' to `%s'"),
397 argv
[i
], predicate_name
);
400 if (predicates
->pred_next
== NULL
)
402 /* No predicates that do something other than set a global variable
403 were given; remove the unneeded initial `(' and add `-print'. */
404 cur_pred
= predicates
;
405 predicates
= last_pred
= predicates
->pred_next
;
406 free ((char *) cur_pred
);
407 parse_print (argv
, &argc
);
409 else if (!default_prints (predicates
->pred_next
))
411 /* One or more predicates that produce output were given;
412 remove the unneeded initial `('. */
413 cur_pred
= predicates
;
414 predicates
= predicates
->pred_next
;
415 free ((char *) cur_pred
);
419 /* `( user-supplied-expression ) -print'. */
420 parse_close (argv
, &argc
);
421 parse_print (argv
, &argc
);
425 fprintf (stderr
, _("Predicate List:\n"));
426 print_list (stderr
, predicates
);
429 /* Done parsing the predicates. Build the evaluation tree. */
430 cur_pred
= predicates
;
431 eval_tree
= get_expr (&cur_pred
, NO_PREC
);
433 /* Check if we have any left-over predicates (this fixes
434 * Debian bug #185202).
436 if (cur_pred
!= NULL
)
438 error (1, 0, _("unexpected extra predicate"));
442 fprintf (stderr
, _("Eval Tree:\n"));
443 print_tree (stderr
, eval_tree
, 0);
446 /* Rearrange the eval tree in optimal-predicate order. */
447 opt_expr (&eval_tree
);
449 /* Determine the point, if any, at which to stat the file. */
450 mark_stat (eval_tree
);
453 fprintf (stderr
, _("Optimized Eval Tree:\n"));
454 print_tree (stderr
, eval_tree
, 0);
455 fprintf (stderr
, _("Optimized command line:\n"));
456 print_optlist(stderr
, eval_tree
);
457 fprintf(stderr
, "\n");
460 starting_desc
= open (".", O_RDONLY
);
461 if (0 <= starting_desc
&& fchdir (starting_desc
) != 0)
463 close (starting_desc
);
466 if (starting_desc
< 0)
468 starting_dir
= xgetcwd ();
470 error (1, errno
, _("cannot get current directory"));
472 if ((*options
.xstat
) (".", &starting_stat_buf
) != 0)
473 error (1, errno
, _("cannot get current directory"));
475 /* If no paths are given, default to ".". */
476 for (i
= end_of_leading_options
; i
< argc
&& strchr ("-!(),", argv
[i
][0]) == NULL
; i
++)
478 process_top_path (argv
[i
]);
481 /* If there were no path arguments, default to ".". */
482 if (i
== end_of_leading_options
)
485 * We use a temporary variable here because some actions modify
486 * the path temporarily. Hence if we use a string constant,
487 * we get a coredump. The best example of this is if we say
488 * "find -printf %H" (note, not "find . -printf %H").
490 char defaultpath
[2] = ".";
491 process_top_path (defaultpath
);
494 return state
.exit_status
;
499 specific_dirname(const char *dir
)
503 if (0 == strcmp(".", dir
))
505 /* OK, what's '.'? */
506 if (NULL
!= getcwd(dirname
, sizeof(dirname
)))
508 return strdup(dirname
);
517 char *result
= canonicalize_filename_mode(dir
, CAN_EXISTING
);
525 static dev_t
*mounted_devices
= NULL
;
526 static size_t num_mounted_devices
= 0u;
530 init_mounted_dev_list()
532 assert(NULL
== mounted_devices
);
533 assert(0 == num_mounted_devices
);
534 mounted_devices
= get_mounted_devices(&num_mounted_devices
);
538 refresh_mounted_dev_list(void)
542 free(mounted_devices
);
545 num_mounted_devices
= 0u;
546 init_mounted_dev_list();
550 /* Search for device DEV in the array LIST, which is of size N. */
552 dev_present(dev_t dev
, const dev_t
*list
, size_t n
)
558 if ( (*list
++) == dev
)
565 enum MountPointStateChange
567 MountPointRecentlyMounted
,
568 MountPointRecentlyUnmounted
,
569 MountPointStateUnchanged
574 static enum MountPointStateChange
575 get_mount_state(dev_t newdev
)
577 int new_is_present
, new_was_present
;
579 new_was_present
= dev_present(newdev
, mounted_devices
, num_mounted_devices
);
580 refresh_mounted_dev_list();
581 new_is_present
= dev_present(newdev
, mounted_devices
, num_mounted_devices
);
583 if (new_was_present
== new_is_present
)
584 return MountPointStateUnchanged
;
585 else if (new_is_present
)
586 return MountPointRecentlyMounted
;
588 return MountPointRecentlyUnmounted
;
592 /* Return non-zero if FS is the name of a filesystem that is likely to
596 fs_likely_to_be_automounted(const char *fs
)
598 return ( (0==strcmp(fs
, "nfs")) || (0==strcmp(fs
, "autofs")));
601 enum WdSanityCheckFatality
603 FATAL_IF_SANITY_CHECK_FAILS
,
604 NON_FATAL_IF_SANITY_CHECK_FAILS
608 /* Examine the results of the stat() of a directory from before we
609 * entered or left it, with the results of stat()ing it afterward. If
610 * these are different, the filesystem tree has been modified while we
611 * were traversing it. That might be an attempt to use a race
612 * condition to persuade find to do something it didn't intend
613 * (e.g. an attempt by an ordinary user to exploit the fact that root
614 * sometimes runs find on the whole filesystem). However, this can
615 * also happen if automount is running (certainly on Solaris). With
616 * automount, moving into a directory can cause a filesystem to be
619 * To cope sensibly with this, we will raise an error if we see the
620 * device number change unless we are chdir()ing into a subdirectory,
621 * and the directory we moved into has been mounted or unmounted "recently".
622 * Here "recently" means since we started "find" or we last re-read
623 * the /etc/mnttab file.
625 * If the device number does not change but the inode does, that is a
628 * If the device number and inode are both the same, we are happy.
630 * If a filesystem is (un)mounted as we chdir() into the directory, that
631 * may mean that we're now examining a section of the filesystem that might
632 * have been excluded from consideration (via -prune or -quit for example).
633 * Hence we print a warning message to indicate that the output of find
634 * might be inconsistent due to the change in the filesystem.
637 wd_sanity_check(const char *thing_to_stat
,
638 const char *program_name
,
642 struct stat
*newinfo
,
645 enum TraversalDirection direction
,
646 enum WdSanityCheckFatality isfatal
,
647 boolean
*changed
) /* output parameter */
650 char *specific_what
= NULL
;
655 if ((*options
.xstat
) (".", newinfo
) != 0)
656 error (1, errno
, "%s", thing_to_stat
);
658 if (old_dev
!= newinfo
->st_dev
)
661 specific_what
= specific_dirname(what
);
662 fstype
= filesystem_type(newinfo
);
663 silent
= fs_likely_to_be_automounted(fstype
);
665 /* This condition is rare, so once we are here it is
666 * reasonable to perform an expensive computation to
667 * determine if we should continue or fail.
669 if (TraversingDown
== direction
)
671 /* We stat()ed a directory, chdir()ed into it (we know this
672 * since direction is TraversingDown), stat()ed it again,
673 * and noticed that the device numbers are different. Check
674 * if the filesystem was recently mounted.
676 * If it was, it looks like chdir()ing into the directory
677 * caused a filesystem to be mounted. Maybe automount is
678 * running. Anyway, that's probably OK - but it happens
679 * only when we are moving downward.
681 * We also allow for the possibility that a similar thing
682 * has happened with the unmounting of a filesystem. This
683 * is much rarer, as it relies on an automounter timeout
684 * occurring at exactly the wrong moment.
686 enum MountPointStateChange transition
= get_mount_state(newinfo
->st_dev
);
689 case MountPointRecentlyUnmounted
:
690 isfatal
= NON_FATAL_IF_SANITY_CHECK_FAILS
;
694 _("Warning: filesystem %s has recently been unmounted."),
699 case MountPointRecentlyMounted
:
700 isfatal
= NON_FATAL_IF_SANITY_CHECK_FAILS
;
704 _("Warning: filesystem %s has recently been mounted."),
709 case MountPointStateUnchanged
:
710 /* leave isfatal as it is */
715 if (FATAL_IF_SANITY_CHECK_FAILS
== isfatal
)
717 fstype
= filesystem_type(newinfo
);
719 _("%s%s changed during execution of %s (old device number %ld, new device number %ld, filesystem type is %s) [ref %ld]"),
724 (long) newinfo
->st_dev
,
732 /* Since the device has changed under us, the inode number
733 * will almost certainly also be different. However, we have
734 * already decided that this is not a problem. Hence we return
735 * without checking the inode number.
742 /* Device number was the same, check if the inode has changed. */
743 if (old_ino
!= newinfo
->st_ino
)
746 specific_what
= specific_dirname(what
);
747 fstype
= filesystem_type(newinfo
);
749 error ((isfatal
== FATAL_IF_SANITY_CHECK_FAILS
) ? 1 : 0,
750 0, /* no relevant errno value */
751 _("%s%s changed during execution of %s (old inode number %ld, new inode number %ld, filesystem type is %s) [ref %ld]"),
756 (long) newinfo
->st_ino
,
769 SafeChdirFailSymlink
,
772 SafeChdirFailWouldBeUnableToReturn
,
773 SafeChdirFailChdirFailed
,
774 SafeChdirFailNonexistent
777 /* Safely perform a change in directory.
781 safely_chdir(const char *dest
,
782 enum TraversalDirection direction
,
783 struct stat
*statbuf_dest
)
785 struct stat statbuf_arrived
;
787 int saved_errno
; /* specific_dirname() changes errno. */
789 boolean rv_set
= false;
791 saved_errno
= errno
= 0;
792 dotfd
= open(".", O_RDONLY
);
795 /* Stat the directory we're going to. */
796 if (0 == options
.xstat(dest
, statbuf_dest
))
799 if (!following_links() && S_ISLNK(statbuf_dest
->st_mode
))
801 rv
= SafeChdirFailSymlink
;
803 saved_errno
= 0; /* silence the error message */
808 /* Although the immediately following chdir() would detect
809 * the fact that this is not a directory for us, this would
810 * result in an extra system call that fails. Anybody
811 * examining the system-call trace should ideally not be
812 * concerned that something is actually failing.
814 if (!S_ISDIR(statbuf_dest
->st_mode
))
816 rv
= SafeChdirFailNotDir
;
818 saved_errno
= 0; /* silence the error message */
822 if (0 == chdir(dest
))
824 /* check we ended up where we wanted to go */
825 boolean changed
= false;
826 wd_sanity_check(".", program_name
, ".",
827 statbuf_dest
->st_dev
,
828 statbuf_dest
->st_ino
,
830 0, __LINE__
, direction
,
831 FATAL_IF_SANITY_CHECK_FAILS
,
839 if (ENOENT
== saved_errno
)
841 rv
= SafeChdirFailNonexistent
;
843 if (options
.ignore_readdir_race
)
844 errno
= 0; /* don't issue err msg */
846 name
= specific_dirname(dest
);
848 else if (ENOTDIR
== saved_errno
)
850 /* This can happen if the we stat a directory,
851 * and then filesystem activity changes it into
854 saved_errno
= 0; /* don't issue err msg */
855 rv
= SafeChdirFailNotDir
;
860 rv
= SafeChdirFailChdirFailed
;
862 name
= specific_dirname(dest
);
870 rv
= SafeChdirFailStat
;
872 name
= specific_dirname(dest
);
873 if ( (ENOENT
== saved_errno
) || (0 == state
.curdepth
))
874 saved_errno
= 0; /* don't issue err msg */
880 /* We do not have read permissions on "." */
881 rv
= SafeChdirFailWouldBeUnableToReturn
;
888 /* We use the same exit path for successs or failure.
889 * which has occurred is recorded in RV.
896 /* do not call error() as this would result in a duplicate error message
897 * when the caller does the same thing.
914 /* Safely go back to the starting directory. */
918 struct stat stat_buf
;
921 if (starting_desc
< 0)
923 if (chdir (starting_dir
) != 0)
924 error (1, errno
, "%s", starting_dir
);
926 wd_sanity_check(starting_dir
,
929 starting_stat_buf
.st_dev
,
930 starting_stat_buf
.st_ino
,
931 &stat_buf
, 0, __LINE__
,
933 FATAL_IF_SANITY_CHECK_FAILS
,
938 if (fchdir (starting_desc
) != 0)
939 error (1, errno
, "%s", starting_dir
);
943 /* Descend PATHNAME, which is a command-line argument. */
945 process_top_path (char *pathname
)
948 state
.path_length
= strlen (pathname
);
949 process_path (pathname
, pathname
, false, ".");
953 /* Info on each directory in the current tree branch, to avoid
954 getting stuck in symbolic link loops. */
955 static struct dir_id
*dir_ids
= NULL
;
956 /* Entries allocated in `dir_ids'. */
957 static int dir_alloc
= 0;
958 /* Index in `dir_ids' of directory currently being searched.
959 This is always the last valid entry. */
960 static int dir_curr
= -1;
961 /* (Arbitrary) number of entries to grow `dir_ids' by. */
962 #define DIR_ALLOC_STEP 32
966 /* We've detected a filesystem loop. This is caused by one of
969 * 1. Option -L is in effect and we've hit a symbolic link that
970 * points to an ancestor. This is harmless. We won't traverse the
973 * 2. We have hit a real cycle in the directory hierarchy. In this
974 * case, we issue a diagnostic message (POSIX requires this) and we
975 * skip that directory entry.
978 issue_loop_warning(const char *name
, const char *pathname
, int level
)
980 struct stat stbuf_link
;
981 if (lstat(name
, &stbuf_link
) != 0)
982 stbuf_link
.st_mode
= S_IFREG
;
984 if (S_ISLNK(stbuf_link
.st_mode
))
987 _("Symbolic link `%s' is part of a loop in the directory hierarchy; we have already visited the directory to which it points."),
992 int distance
= 1 + (dir_curr
-level
);
993 /* We have found an infinite loop. POSIX requires us to
994 * issue a diagnostic. Usually we won't get to here
995 * because when the leaf optimisation is on, it will cause
996 * the subdirectory to be skipped. If /a/b/c/d is a hard
997 * link to /a/b, then the link count of /a/b/c is 2,
998 * because the ".." entry of /b/b/c/d points to /a, not
1002 _("Filesystem loop detected; `%s' has the same device number and inode as a directory which is %d %s."),
1006 _("level higher in the filesystem hierarchy") :
1007 _("levels higher in the filesystem hierarchy")));
1011 /* Recursively descend path PATHNAME, applying the predicates.
1012 LEAF is true if PATHNAME is known to be in a directory that has no
1013 more unexamined subdirectories, and therefore it is not a directory.
1014 Knowing this allows us to avoid calling stat as long as possible for
1017 NAME is PATHNAME relative to the current directory. We access NAME
1020 PARENT is the path of the parent of NAME, relative to find's
1023 Return nonzero iff PATHNAME is a directory. */
1026 process_path (char *pathname
, char *name
, boolean leaf
, char *parent
)
1028 struct stat stat_buf
;
1029 static dev_t root_dev
; /* Device ID of current argument pathname. */
1032 /* Assume it is a non-directory initially. */
1033 stat_buf
.st_mode
= 0;
1035 state
.rel_pathname
= name
;
1038 state
.have_stat
= false;
1041 if ((*options
.xstat
) (name
, &stat_buf
) != 0)
1043 if (!options
.ignore_readdir_race
|| (errno
!= ENOENT
) )
1045 error (0, errno
, "%s", pathname
);
1046 state
.exit_status
= 1;
1050 state
.have_stat
= true;
1053 if (!S_ISDIR (stat_buf
.st_mode
))
1055 if (state
.curdepth
>= options
.mindepth
)
1056 apply_predicate (pathname
, &stat_buf
, eval_tree
);
1060 /* From here on, we're working on a directory. */
1062 state
.stop_at_current_level
=
1063 options
.maxdepth
>= 0
1064 && state
.curdepth
>= options
.maxdepth
;
1066 /* If we've already seen this directory on this branch,
1067 don't descend it again. */
1068 for (i
= 0; i
<= dir_curr
; i
++)
1069 if (stat_buf
.st_ino
== dir_ids
[i
].ino
&&
1070 stat_buf
.st_dev
== dir_ids
[i
].dev
)
1072 state
.stop_at_current_level
= true;
1073 issue_loop_warning(name
, pathname
, i
);
1076 if (dir_alloc
<= ++dir_curr
)
1078 dir_alloc
+= DIR_ALLOC_STEP
;
1079 dir_ids
= (struct dir_id
*)
1080 xrealloc ((char *) dir_ids
, dir_alloc
* sizeof (struct dir_id
));
1082 dir_ids
[dir_curr
].ino
= stat_buf
.st_ino
;
1083 dir_ids
[dir_curr
].dev
= stat_buf
.st_dev
;
1085 if (options
.stay_on_filesystem
)
1087 if (state
.curdepth
== 0)
1088 root_dev
= stat_buf
.st_dev
;
1089 else if (stat_buf
.st_dev
!= root_dev
)
1090 state
.stop_at_current_level
= true;
1093 if (options
.do_dir_first
&& state
.curdepth
>= options
.mindepth
)
1094 apply_predicate (pathname
, &stat_buf
, eval_tree
);
1097 fprintf(stderr
, "pathname = %s, stop_at_current_level = %d\n",
1098 pathname
, state
.stop_at_current_level
);
1101 if (state
.stop_at_current_level
== false)
1102 /* Scan directory on disk. */
1103 process_dir (pathname
, name
, strlen (pathname
), &stat_buf
, parent
);
1105 if (options
.do_dir_first
== false && state
.curdepth
>= options
.mindepth
)
1107 state
.rel_pathname
= name
;
1108 apply_predicate (pathname
, &stat_buf
, eval_tree
);
1116 /* Scan directory PATHNAME and recurse through process_path for each entry.
1118 PATHLEN is the length of PATHNAME.
1120 NAME is PATHNAME relative to the current directory.
1122 STATP is the results of *options.xstat on it.
1124 PARENT is the path of the parent of NAME, relative to find's
1125 starting directory. */
1128 process_dir (char *pathname
, char *name
, int pathlen
, struct stat
*statp
, char *parent
)
1130 char *name_space
; /* Names of files in PATHNAME. */
1131 int subdirs_left
; /* Number of unexamined subdirs in PATHNAME. */
1132 struct stat stat_buf
;
1134 subdirs_left
= statp
->st_nlink
- 2; /* Account for name and ".". */
1137 name_space
= savedir (name
);
1138 if (name_space
== NULL
)
1141 error (0, errno
, "%s", pathname
);
1142 state
.exit_status
= 1;
1146 register char *namep
; /* Current point in `name_space'. */
1147 char *cur_path
; /* Full path of each file to process. */
1148 char *cur_name
; /* Base name of each file to process. */
1149 unsigned cur_path_size
; /* Bytes allocated for `cur_path'. */
1150 register unsigned file_len
; /* Length of each path to process. */
1151 register unsigned pathname_len
; /* PATHLEN plus trailing '/'. */
1153 if (pathname
[pathlen
- 1] == '/')
1154 pathname_len
= pathlen
+ 1; /* For '\0'; already have '/'. */
1156 pathname_len
= pathlen
+ 2; /* For '/' and '\0'. */
1161 if (strcmp (name
, "."))
1163 enum SafeChdirStatus status
= safely_chdir (name
, TraversingDown
, &stat_buf
);
1167 /* If there had been a change but wd_sanity_check()
1168 * accepted it, we need to accept that on the
1169 * way back up as well, so modify our record
1170 * of what we think we should see later.
1171 * If there was no change, the assignments are a no-op.
1173 dir_ids
[dir_curr
].dev
= stat_buf
.st_dev
;
1174 dir_ids
[dir_curr
].ino
= stat_buf
.st_ino
;
1177 case SafeChdirFailNonexistent
:
1178 case SafeChdirFailStat
:
1179 case SafeChdirFailWouldBeUnableToReturn
:
1180 case SafeChdirFailSymlink
:
1181 case SafeChdirFailNotDir
:
1182 case SafeChdirFailChdirFailed
:
1183 error (0, errno
, "%s", pathname
);
1184 state
.exit_status
= 1;
1189 if (strcmp (name
, ".") && chdir (name
) < 0)
1191 error (0, errno
, "%s", pathname
);
1196 /* Check that we are where we should be. */
1199 boolean changed
= false;
1200 wd_sanity_check(pathname
,
1203 dir_ids
[dir_curr
].dev
,
1204 dir_ids
[dir_curr
].ino
,
1205 &stat_buf
, 0, __LINE__
,
1207 FATAL_IF_SANITY_CHECK_FAILS
,
1211 /* If there had been a change but wd_sanity_check()
1212 * accepted it, we need to accept that on the
1213 * way back up as well, so modify our record
1214 * of what we think we should see later.
1216 dir_ids
[dir_curr
].dev
= stat_buf
.st_dev
;
1217 dir_ids
[dir_curr
].ino
= stat_buf
.st_ino
;
1222 for (namep
= name_space
; *namep
; namep
+= file_len
- pathname_len
+ 1)
1224 /* Append this directory entry's name to the path being searched. */
1225 file_len
= pathname_len
+ strlen (namep
);
1226 if (file_len
> cur_path_size
)
1228 while (file_len
> cur_path_size
)
1229 cur_path_size
+= 1024;
1232 cur_path
= xmalloc (cur_path_size
);
1233 strcpy (cur_path
, pathname
);
1234 cur_path
[pathname_len
- 2] = '/';
1236 cur_name
= cur_path
+ pathname_len
- 1;
1237 strcpy (cur_name
, namep
);
1240 if (!options
.no_leaf_check
)
1241 /* Normal case optimization.
1242 On normal Unix filesystems, a directory that has no
1243 subdirectories has two links: its name, and ".". Any
1244 additional links are to the ".." entries of its
1245 subdirectories. Once we have processed as many
1246 subdirectories as there are additional links, we know
1247 that the rest of the entries are non-directories --
1248 in other words, leaf files. */
1249 subdirs_left
-= process_path (cur_path
, cur_name
,
1250 subdirs_left
== 0, pathname
);
1252 /* There might be weird (e.g., CD-ROM or MS-DOS) filesystems
1253 mounted, which don't have Unix-like directory link counts. */
1254 process_path (cur_path
, cur_name
, false, pathname
);
1258 if (strcmp (name
, "."))
1260 enum SafeChdirStatus status
;
1262 boolean changed
= false;
1264 /* We could go back and do the next command-line arg
1265 instead, maybe using longjmp. */
1267 boolean deref
= following_links() ? true : false;
1269 if ( (state
.curdepth
>0) && !deref
)
1277 status
= safely_chdir (dir
, TraversingUp
, &stat_buf
);
1283 case SafeChdirFailNonexistent
:
1284 case SafeChdirFailStat
:
1285 case SafeChdirFailWouldBeUnableToReturn
:
1286 case SafeChdirFailSymlink
:
1287 case SafeChdirFailNotDir
:
1288 case SafeChdirFailChdirFailed
:
1289 error (1, errno
, "%s", pathname
);
1295 did
.dev
= dir_ids
[dir_curr
-1].dev
;
1296 did
.ino
= dir_ids
[dir_curr
-1].ino
;
1300 did
.dev
= starting_stat_buf
.st_dev
;
1301 did
.ino
= starting_stat_buf
.st_ino
;
1304 wd_sanity_check(pathname
,
1313 FATAL_IF_SANITY_CHECK_FAILS
,
1317 if (strcmp (name
, "."))
1319 /* We could go back and do the next command-line arg
1320 instead, maybe using longjmp. */
1322 boolean deref
= following_links() ? true : false;
1332 if (chdir (dir
) != 0)
1333 error (1, errno
, "%s", parent
);
1335 /* Check that we are where we should be. */
1338 boolean changed
= false;
1340 int problem_is_with_parent
;
1342 memset(&tmp
, 0, sizeof(tmp
));
1345 tmp
.st_dev
= dir_ids
[dir_curr
-1].dev
;
1346 tmp
.st_ino
= dir_ids
[dir_curr
-1].ino
;
1350 tmp
.st_dev
= starting_stat_buf
.st_dev
;
1351 tmp
.st_ino
= starting_stat_buf
.st_ino
;
1354 problem_is_with_parent
= deref
? 1 : 0;
1355 wd_sanity_check(pathname
,
1361 problem_is_with_parent
, __LINE__
,
1363 FATAL_IF_SANITY_CHECK_FAILS
,
1375 /* Return true if there are no predicates with no_default_print in
1376 predicate list PRED, false if there are any.
1377 Returns true if default print should be performed */
1380 default_prints (struct predicate
*pred
)
1382 while (pred
!= NULL
)
1384 if (pred
->no_default_print
)
1386 pred
= pred
->pred_next
;