1 /* find -- search for files in a directory hierarchy
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003 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>. */
37 #include "../gnulib/lib/human.h"
38 #include "../gnulib/lib/canonicalize.h"
40 #include "../gnulib/lib/savedir.h"
48 # define _(Text) gettext (Text)
51 #define textdomain(Domain)
52 #define bindtextdomain(Package, Directory)
55 # define N_(String) gettext_noop (String)
57 /* See locate.c for explanation as to why not use (String) */
58 # define N_(String) String
61 #define apply_predicate(pathname, stat_buf_ptr, node) \
62 (*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
65 static void init_mount_point_list(void);
66 static void process_top_path
PARAMS((char *pathname
));
67 static int process_path
PARAMS((char *pathname
, char *name
, boolean leaf
, char *parent
));
68 static void process_dir
PARAMS((char *pathname
, char *name
, int pathlen
, struct stat
*statp
, char *parent
));
70 static boolean no_side_effects
PARAMS((struct predicate
*pred
));
72 static boolean default_prints
PARAMS((struct predicate
*pred
));
74 /* Name this program was run with. */
77 /* All predicates for each path to process. */
78 struct predicate
*predicates
;
80 /* The last predicate allocated. */
81 struct predicate
*last_pred
;
83 /* The root of the evaluation tree. */
84 static struct predicate
*eval_tree
;
86 /* If true, process directory before contents. True unless -depth given. */
89 /* If >=0, don't descend more than this many levels of subdirectories. */
92 /* If >=0, don't process files above this level. */
95 /* Current depth; 0 means current path is a command line arg. */
98 /* Output block size. */
99 int output_block_size
;
101 /* Time at start of execution. */
104 /* Seconds between 00:00 1/1/70 and either one day before now
105 (the default), or the start of today (if -daystart is given). */
106 time_t cur_day_start
;
108 /* If true, cur_day_start has been adjusted to the start of the day. */
111 /* If true, do not assume that files in directories with nlink == 2
112 are non-directories. */
113 boolean no_leaf_check
;
115 /* If true, don't cross filesystem boundaries. */
116 boolean stay_on_filesystem
;
118 /* If true, don't descend past current directory.
119 Can be set by -prune, -maxdepth, and -xdev/-mount. */
120 boolean stop_at_current_level
;
122 /* The full path of the initial working directory, or "." if
123 STARTING_DESC is nonnegative. */
124 char const *starting_dir
= ".";
126 /* A file descriptor open to the initial working directory.
127 Doing it this way allows us to work when the i.w.d. has
128 unreadable parents. */
131 /* The stat buffer of the initial working directory. */
132 struct stat starting_stat_buf
;
134 /* If true, we have called stat on the current path. */
137 /* The file being operated on, relative to the current directory.
138 Used for stat, readlink, remove, and opendir. */
141 /* Length of current path. */
144 /* true if following symlinks. Should be consistent with xstat. */
145 /* boolean dereference; */
146 enum SymlinkOption symlink_handling
;
149 /* Pointer to the function used to stat files. */
152 /* Status value to return to system. */
155 /* If true, we ignore the problem where we find that a directory entry
156 * no longer exists by the time we get around to processing it.
158 boolean ignore_readdir_race
;
161 /* If true, we issue warning messages
166 enum TraversalDirection
173 /* optionh_stat() implements the stat operation when the -H option is
176 * If the item to be examined is a command-line argument, we follow
177 * symbolic links. If the stat() call fails on the command-line item,
178 * we fall back on the properties of the symbolic link.
180 * If the item to be examined is not a command-line argument, we
181 * examine the link itself.
184 optionh_stat(const char *name
, struct stat
*p
)
188 /* This file is from the command line; deference the link (if it
191 if (0 == stat(name
, p
))
198 /* fallback - return the information for the link itself. */
199 return lstat(name
, p
);
204 /* Not a file on the command line; do not derefernce the link.
206 return lstat(name
, p
);
210 /* optionl_stat() implements the stat operation when the -L option is
211 * in effect. That option makes us examine the thing the symbolic
212 * link points to, not the symbolic link itself.
215 optionl_stat(const char *name
, struct stat
*p
)
217 if (0 == stat(name
, p
))
219 return 0; /* normal case. */
223 return lstat(name
, p
); /* can't follow link, return the link itself. */
227 /* optionp_stat() implements the stat operation when the -P option is
228 * in effect (this is also the default). That option makes us examine
229 * the symbolic link itself, not the thing it points to.
232 optionp_stat(const char *name
, struct stat
*p
)
234 return lstat(name
, p
);
239 debug_stat (const char *file
, struct stat
*bufp
)
241 fprintf (stderr
, "debug_stat (%s)\n", file
);
242 switch (symlink_handling
)
244 case SYMLINK_ALWAYS_DEREF
:
245 return optionl_stat(file
, bufp
);
246 case SYMLINK_DEREF_ARGSONLY
:
247 return optionh_stat(file
, bufp
);
248 case SYMLINK_NEVER_DEREF
:
249 return optionp_stat(file
, bufp
);
252 #endif /* DEBUG_STAT */
255 set_follow_state(enum SymlinkOption opt
)
259 case SYMLINK_ALWAYS_DEREF
: /* -L */
260 xstat
= optionl_stat
;
261 no_leaf_check
= false;
264 case SYMLINK_NEVER_DEREF
: /* -P (default) */
265 xstat
= optionp_stat
;
266 /* Can't turn on no_leaf_check because the user might have specified
271 case SYMLINK_DEREF_ARGSONLY
: /* -H */
272 xstat
= optionh_stat
;
273 no_leaf_check
= true;
276 /* For DBEUG_STAT, the choice is made at runtime within debug_stat()
277 * by checking the contents of the symlink_handling variable.
279 #if defined(DEBUG_STAT)
281 #endif /* !DEBUG_STAT */
286 main (int argc
, char **argv
)
289 PFB parse_function
; /* Pointer to the function which parses. */
290 struct predicate
*cur_pred
;
291 char *predicate_name
; /* Name of predicate being parsed. */
292 int end_of_leading_options
= 0; /* First arg after any -H/-L etc. */
293 program_name
= argv
[0];
295 #ifdef HAVE_SETLOCALE
296 setlocale (LC_ALL
, "");
298 bindtextdomain (PACKAGE
, LOCALEDIR
);
299 textdomain (PACKAGE
);
314 maxdepth
= mindepth
= -1;
315 start_time
= time (NULL
);
316 cur_day_start
= start_time
- DAYSECS
;
318 no_leaf_check
= false;
319 stay_on_filesystem
= false;
320 ignore_readdir_race
= false;
323 #if defined(DEBUG_STAT)
325 #endif /* !DEBUG_STAT */
328 human_block_size (getenv ("FIND_BLOCK_SIZE"), 0, &output_block_size
);
330 if (getenv("POSIXLY_CORRECT"))
331 output_block_size
= 512;
333 output_block_size
= 1024;
335 if (getenv("FIND_BLOCK_SIZE"))
337 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"));
340 set_follow_state(SYMLINK_NEVER_DEREF
); /* The default is equivalent to -P. */
342 init_mount_point_list();
347 printf ("cur_day_start = %s", ctime (&cur_day_start
));
350 /* Check for -P, -H or -L options. */
351 for (i
=1; (end_of_leading_options
= i
) < argc
; ++i
)
353 if (0 == strcmp("-H", argv
[i
]))
355 /* Meaning: dereference symbolic links on command line, but nowhere else. */
356 set_follow_state(SYMLINK_DEREF_ARGSONLY
);
358 else if (0 == strcmp("-L", argv
[i
]))
360 /* Meaning: dereference all symbolic links. */
361 set_follow_state(SYMLINK_ALWAYS_DEREF
);
363 else if (0 == strcmp("-P", argv
[i
]))
365 /* Meaning: never dereference symbolic links (default). */
366 set_follow_state(SYMLINK_NEVER_DEREF
);
368 else if (0 == strcmp("--", argv
[i
]))
370 /* -- signifies the end of options. */
371 end_of_leading_options
= i
+1; /* Next time start with the next option */
376 /* Hmm, must be one of
380 end_of_leading_options
= i
; /* Next time start with this option */
385 /* We are now processing the part of the "find" command line
386 * after the -H/-L options (if any).
389 /* fprintf(stderr, "rest: optind=%ld\n", (long)optind); */
391 /* Find where in ARGV the predicates begin. */
392 for (i
= end_of_leading_options
; i
< argc
&& strchr ("-!(),", argv
[i
][0]) == NULL
; i
++)
394 /* fprintf(stderr, "Looks like %s is not a predicate\n", argv[i]); */
398 /* Enclose the expression in `( ... )' so a default -print will
399 apply to the whole expression. */
400 parse_open (argv
, &argc
);
401 /* Build the input order list. */
404 if (strchr ("-!(),", argv
[i
][0]) == NULL
)
405 usage (_("paths must precede expression"));
406 predicate_name
= argv
[i
];
407 parse_function
= find_parser (predicate_name
);
408 if (parse_function
== NULL
)
409 /* Command line option not recognized */
410 error (1, 0, _("invalid predicate `%s'"), predicate_name
);
412 if (!(*parse_function
) (argv
, &i
))
415 /* Command line option requires an argument */
416 error (1, 0, _("missing argument to `%s'"), predicate_name
);
418 error (1, 0, _("invalid argument `%s' to `%s'"),
419 argv
[i
], predicate_name
);
422 if (predicates
->pred_next
== NULL
)
424 /* No predicates that do something other than set a global variable
425 were given; remove the unneeded initial `(' and add `-print'. */
426 cur_pred
= predicates
;
427 predicates
= last_pred
= predicates
->pred_next
;
428 free ((char *) cur_pred
);
429 parse_print (argv
, &argc
);
431 else if (!default_prints (predicates
->pred_next
))
433 /* One or more predicates that produce output were given;
434 remove the unneeded initial `('. */
435 cur_pred
= predicates
;
436 predicates
= predicates
->pred_next
;
437 free ((char *) cur_pred
);
441 /* `( user-supplied-expression ) -print'. */
442 parse_close (argv
, &argc
);
443 parse_print (argv
, &argc
);
447 printf (_("Predicate List:\n"));
448 print_list (predicates
);
451 /* Done parsing the predicates. Build the evaluation tree. */
452 cur_pred
= predicates
;
453 eval_tree
= get_expr (&cur_pred
, NO_PREC
);
455 /* Check if we have any left-over predicates (this fixes
456 * Debian bug #185202).
458 if (cur_pred
!= NULL
)
460 error (1, 0, _("unexpected extra predicate"));
464 printf (_("Eval Tree:\n"));
465 print_tree (eval_tree
, 0);
468 /* Rearrange the eval tree in optimal-predicate order. */
469 opt_expr (&eval_tree
);
471 /* Determine the point, if any, at which to stat the file. */
472 mark_stat (eval_tree
);
475 printf (_("Optimized Eval Tree:\n"));
476 print_tree (eval_tree
, 0);
479 starting_desc
= open (".", O_RDONLY
);
480 if (0 <= starting_desc
&& fchdir (starting_desc
) != 0)
482 close (starting_desc
);
485 if (starting_desc
< 0)
487 starting_dir
= xgetcwd ();
489 error (1, errno
, _("cannot get current directory"));
491 if ((*xstat
) (".", &starting_stat_buf
) != 0)
492 error (1, errno
, _("cannot get current directory"));
494 /* If no paths are given, default to ".". */
495 for (i
= end_of_leading_options
; i
< argc
&& strchr ("-!(),", argv
[i
][0]) == NULL
; i
++)
497 process_top_path (argv
[i
]);
500 /* If there were no path arguments, default to ".". */
501 if (i
== end_of_leading_options
)
504 * We use a temporary variable here because some actions modify
505 * the path temporarily. Hence if we use a string constant,
506 * we get a coredump. The best example of this is if we say
507 * "find -printf %H" (note, not "find . -printf %H").
509 char defaultpath
[2] = ".";
510 process_top_path (defaultpath
);
519 specific_dirname(const char *dir
)
523 if (0 == strcmp(".", dir
))
525 /* OK, what's '.'? */
526 if (NULL
!= getcwd(dirname
, sizeof(dirname
)))
528 return strdup(dirname
);
537 return canonicalize_filename_mode(dir
, CAN_EXISTING
);
541 enum MountPointStateChange
543 MountPointRecentlyMounted
,
544 MountPointRecentlyUnmounted
,
545 MountPointStateUnchanged
548 static char *mount_points
= NULL
;
550 /* Initialise our idea of what the list of mount points is.
551 * this function is called exactly once.
554 init_mount_point_list(void)
556 assert(NULL
== mount_points
);
557 mount_points
= get_mounted_filesystems();
560 /* list_item_present: Search for NEEDLE in HAYSTACK.
562 * NEEDLE is a normal C string. HAYSTACK is a list of concatenated C strings,
563 * each with a terminating NUL. The last item in the list is identified by
564 * the fact that its terminating NUL is itself followed by a second NUL.
566 * This data structure does not lend itself to fast searching, but we only
567 * do this when wd_sanity_check() thinks that a filesystem might have been
568 * mounted or unmounted. That doesn't happen very often.
571 list_item_present(const char *needle
, const char *haystack
)
573 if (NULL
!= haystack
)
575 const char *s
= haystack
;
578 if (0 == strcmp(s
, needle
))
585 ++s
; /* skip the first NUL. */
593 /* Determine if a directory has recently had a filesystem
594 * mounted on it or unmounted from it.
596 static enum MountPointStateChange
597 get_mount_point_state(const char *dir
)
599 int was_mounted
, is_mounted
;
601 was_mounted
= list_item_present(dir
, mount_points
);
607 mount_points
= get_mounted_filesystems();
609 is_mounted
= list_item_present(dir
, mount_points
);
611 if (was_mounted
== is_mounted
)
612 return MountPointStateUnchanged
;
614 return MountPointRecentlyMounted
;
616 return MountPointRecentlyUnmounted
;
620 /* Examine the results of the stat() of a directory from before we
621 * entered or left it, with the results of stat()ing it afterward. If
622 * these are different, the filesystem tree has been modified while we
623 * were traversing it. That might be an attempt to use a race
624 * condition to persuade find to do something it didn't intend
625 * (e.g. an attempt by an ordinary user to exploit the fact that root
626 * sometimes runs find on the whole filesystem). However, this can
627 * also happen if automount is running (certainly on Solaris). With
628 * automount, moving into a directory can cause a filesystem to be
631 * To cope sensibly with this, we will raise an error if we see the
632 * device number change unless we are chdir()ing into a subdirectory,
633 * and the directory we moved into has been mounted or unmounted "recently".
634 * Here "recently" means since we started "find" or we last re-read
635 * the /etc/mnttab file.
637 * If the device number does not change but the inode does, that is a
640 * If the device number and inode are both the same, we are happy.
642 * If a filesystem is (un)mounted as we chdir() into the directory, that
643 * may mean that we're now examining a section of the filesystem that might
644 * have been excluded from consideration (via -prune or -quit for example).
645 * Hence we print a warning message to indicate that the output of find
646 * might be inconsistent due to the change in the filesystem.
649 wd_sanity_check(const char *thing_to_stat
,
650 const char *program_name
,
652 const struct stat
*oldinfo
,
653 struct stat
*newinfo
,
656 enum TraversalDirection direction
)
659 char *specific_what
= NULL
;
663 if ((*xstat
) (".", newinfo
) != 0)
664 error (1, errno
, "%s", thing_to_stat
);
666 if (oldinfo
->st_dev
!= newinfo
->st_dev
)
668 specific_what
= specific_dirname(what
);
670 /* This condition is rare, so once we are here it is
671 * reasonable to perform an expensive computation to
672 * determine if we should continue or fail.
674 if (TraversingDown
== direction
)
676 /* We stat()ed a directory, chdir()ed into it (we know this
677 * since direction is TraversingDown), stat()ed it again,
678 * and noticed that the device numbers are different. Check
679 * if the filesystem was recently mounted.
681 * If it was, it looks like chdir()ing into the directory
682 * caused a filesystem to be mounted. Maybe automount is
683 * running. Anyway, that's probably OK - but it happens
684 * only when we are moving downward.
686 * We also allow for the possibility that a similar thing
687 * has happened with the unmounting of a filesystem. This
688 * is much rarer, as it relies on an automounter timeout
689 * occurring at exactly the wrong moment.
691 enum MountPointStateChange transition
= get_mount_point_state(specific_what
);
694 case MountPointRecentlyUnmounted
:
697 _("Warning: filesystem %s has recently been unmounted."),
701 case MountPointRecentlyMounted
:
704 _("Warning: filesystem %s has recently been mounted."),
708 case MountPointStateUnchanged
:
716 fstype
= filesystem_type(thing_to_stat
, ".", newinfo
);
718 _("%s%s changed during execution of %s (old device number %ld, new device number %ld, filesystem type is %s) [ref %ld]"),
722 (long) oldinfo
->st_dev
,
723 (long) newinfo
->st_dev
,
729 /* Since the device has changed under us, the inode number
730 * will almost certainly also be different. However, we have
731 * already decided that this is not a problem. Hence we return
732 * without checking the inode number.
739 /* Device number was the same, check if the inode has changed. */
740 if (oldinfo
->st_ino
!= newinfo
->st_ino
)
742 specific_what
= specific_dirname(what
);
743 fstype
= filesystem_type(thing_to_stat
, ".", newinfo
);
746 _("%s%s changed during execution of %s (old inode number %ld, new inode number %ld, filesystem type is %s) [ref %ld]"),
750 (long) oldinfo
->st_ino
,
751 (long) newinfo
->st_ino
,
759 /* Safely go back to the starting directory. */
763 struct stat stat_buf
;
765 if (starting_desc
< 0)
767 if (chdir (starting_dir
) != 0)
768 error (1, errno
, "%s", starting_dir
);
770 wd_sanity_check(starting_dir
,
771 program_name
, starting_dir
,
772 &starting_stat_buf
, &stat_buf
, 0, __LINE__
,
777 if (fchdir (starting_desc
) != 0)
778 error (1, errno
, "%s", starting_dir
);
782 /* Descend PATHNAME, which is a command-line argument. */
785 process_top_path (char *pathname
)
787 struct stat stat_buf
, cur_stat_buf
;
790 path_length
= strlen (pathname
);
792 /* We stat each pathname given on the command-line twice --
793 once here and once in process_path. It's not too bad, though,
794 since the kernel can read the stat information out of its inode
795 cache the second time. */
796 if ((*xstat
) (pathname
, &stat_buf
) == 0 && S_ISDIR (stat_buf
.st_mode
))
798 if (chdir (pathname
) < 0)
800 if (!ignore_readdir_race
|| (errno
!= ENOENT
) )
802 error (0, errno
, "%s", pathname
);
808 /* Check that we are where we should be. */
809 wd_sanity_check(pathname
, program_name
,
811 &stat_buf
, &cur_stat_buf
, 0, __LINE__
,
814 process_path (pathname
, ".", false, ".");
818 process_path (pathname
, pathname
, false, ".");
821 /* Info on each directory in the current tree branch, to avoid
822 getting stuck in symbolic link loops. */
828 static struct dir_id
*dir_ids
= NULL
;
829 /* Entries allocated in `dir_ids'. */
830 static int dir_alloc
= 0;
831 /* Index in `dir_ids' of directory currently being searched.
832 This is always the last valid entry. */
833 static int dir_curr
= -1;
834 /* (Arbitrary) number of entries to grow `dir_ids' by. */
835 #define DIR_ALLOC_STEP 32
837 /* Recursively descend path PATHNAME, applying the predicates.
838 LEAF is true if PATHNAME is known to be in a directory that has no
839 more unexamined subdirectories, and therefore it is not a directory.
840 Knowing this allows us to avoid calling stat as long as possible for
843 NAME is PATHNAME relative to the current directory. We access NAME
846 PARENT is the path of the parent of NAME, relative to find's
849 Return nonzero iff PATHNAME is a directory. */
852 process_path (char *pathname
, char *name
, boolean leaf
, char *parent
)
854 struct stat stat_buf
;
855 static dev_t root_dev
; /* Device ID of current argument pathname. */
858 /* Assume it is a non-directory initially. */
859 stat_buf
.st_mode
= 0;
867 if ((*xstat
) (name
, &stat_buf
) != 0)
869 if (!ignore_readdir_race
|| (errno
!= ENOENT
) )
871 error (0, errno
, "%s", pathname
);
879 if (!S_ISDIR (stat_buf
.st_mode
))
881 if (curdepth
>= mindepth
)
882 apply_predicate (pathname
, &stat_buf
, eval_tree
);
886 /* From here on, we're working on a directory. */
888 stop_at_current_level
= maxdepth
>= 0 && curdepth
>= maxdepth
;
890 /* If we've already seen this directory on this branch,
891 don't descend it again. */
892 for (i
= 0; i
<= dir_curr
; i
++)
893 if (stat_buf
.st_ino
== dir_ids
[i
].ino
&&
894 stat_buf
.st_dev
== dir_ids
[i
].dev
)
895 stop_at_current_level
= true;
897 if (dir_alloc
<= ++dir_curr
)
899 dir_alloc
+= DIR_ALLOC_STEP
;
900 dir_ids
= (struct dir_id
*)
901 xrealloc ((char *) dir_ids
, dir_alloc
* sizeof (struct dir_id
));
903 dir_ids
[dir_curr
].ino
= stat_buf
.st_ino
;
904 dir_ids
[dir_curr
].dev
= stat_buf
.st_dev
;
906 if (stay_on_filesystem
)
909 root_dev
= stat_buf
.st_dev
;
910 else if (stat_buf
.st_dev
!= root_dev
)
911 stop_at_current_level
= true;
914 if (do_dir_first
&& curdepth
>= mindepth
)
915 apply_predicate (pathname
, &stat_buf
, eval_tree
);
918 fprintf(stderr
, "pathname = %s, stop_at_current_level = %d\n",
919 pathname
, stop_at_current_level
);
922 if (stop_at_current_level
== false)
923 /* Scan directory on disk. */
924 process_dir (pathname
, name
, strlen (pathname
), &stat_buf
, parent
);
926 if (do_dir_first
== false && curdepth
>= mindepth
)
929 apply_predicate (pathname
, &stat_buf
, eval_tree
);
937 /* Scan directory PATHNAME and recurse through process_path for each entry.
939 PATHLEN is the length of PATHNAME.
941 NAME is PATHNAME relative to the current directory.
943 STATP is the results of *xstat on it.
945 PARENT is the path of the parent of NAME, relative to find's
946 starting directory. */
949 process_dir (char *pathname
, char *name
, int pathlen
, struct stat
*statp
, char *parent
)
951 char *name_space
; /* Names of files in PATHNAME. */
952 int subdirs_left
; /* Number of unexamined subdirs in PATHNAME. */
953 struct stat stat_buf
;
955 subdirs_left
= statp
->st_nlink
- 2; /* Account for name and ".". */
958 name_space
= savedir (name
);
959 if (name_space
== NULL
)
963 error (0, errno
, "%s", pathname
);
967 error (1, 0, _("virtual memory exhausted"));
971 register char *namep
; /* Current point in `name_space'. */
972 char *cur_path
; /* Full path of each file to process. */
973 char *cur_name
; /* Base name of each file to process. */
974 unsigned cur_path_size
; /* Bytes allocated for `cur_path'. */
975 register unsigned file_len
; /* Length of each path to process. */
976 register unsigned pathname_len
; /* PATHLEN plus trailing '/'. */
978 if (pathname
[pathlen
- 1] == '/')
979 pathname_len
= pathlen
+ 1; /* For '\0'; already have '/'. */
981 pathname_len
= pathlen
+ 2; /* For '/' and '\0'. */
985 if (strcmp (name
, ".") && chdir (name
) < 0)
987 error (0, errno
, "%s", pathname
);
992 /* Check that we are where we should be. */
995 struct stat tmp
= {0};
996 tmp
.st_dev
= dir_ids
[dir_curr
].dev
;
997 tmp
.st_ino
= dir_ids
[dir_curr
].ino
;
998 wd_sanity_check(pathname
,
1001 &tmp
, &stat_buf
, 0, __LINE__
,
1005 for (namep
= name_space
; *namep
; namep
+= file_len
- pathname_len
+ 1)
1007 /* Append this directory entry's name to the path being searched. */
1008 file_len
= pathname_len
+ strlen (namep
);
1009 if (file_len
> cur_path_size
)
1011 while (file_len
> cur_path_size
)
1012 cur_path_size
+= 1024;
1015 cur_path
= xmalloc (cur_path_size
);
1016 strcpy (cur_path
, pathname
);
1017 cur_path
[pathname_len
- 2] = '/';
1019 cur_name
= cur_path
+ pathname_len
- 1;
1020 strcpy (cur_name
, namep
);
1024 /* Normal case optimization.
1025 On normal Unix filesystems, a directory that has no
1026 subdirectories has two links: its name, and ".". Any
1027 additional links are to the ".." entries of its
1028 subdirectories. Once we have processed as many
1029 subdirectories as there are additional links, we know
1030 that the rest of the entries are non-directories --
1031 in other words, leaf files. */
1032 subdirs_left
-= process_path (cur_path
, cur_name
,
1033 subdirs_left
== 0, pathname
);
1035 /* There might be weird (e.g., CD-ROM or MS-DOS) filesystems
1036 mounted, which don't have Unix-like directory link counts. */
1037 process_path (cur_path
, cur_name
, false, pathname
);
1041 if (strcmp (name
, "."))
1043 /* We could go back and do the next command-line arg
1044 instead, maybe using longjmp. */
1047 if (symlink_handling
== SYMLINK_ALWAYS_DEREF
)
1049 else if (symlink_handling
== SYMLINK_DEREF_ARGSONLY
&& (curdepth
== 0))
1062 if (chdir (dir
) != 0)
1063 error (1, errno
, "%s", parent
);
1065 /* Check that we are where we should be. */
1069 int problem_is_with_parent
;
1073 tmp
.st_dev
= dir_ids
[dir_curr
-1].dev
;
1074 tmp
.st_ino
= dir_ids
[dir_curr
-1].ino
;
1078 tmp
.st_dev
= starting_stat_buf
.st_dev
;
1079 tmp
.st_ino
= starting_stat_buf
.st_ino
;
1082 problem_is_with_parent
= deref
? 1 : 0;
1083 wd_sanity_check(pathname
,
1085 deref
? parent
: starting_dir
,
1087 problem_is_with_parent
, __LINE__
,
1099 /* Return true if there are no side effects in any of the predicates in
1100 predicate list PRED, false if there are any. */
1103 no_side_effects (struct predicate
*pred
)
1105 while (pred
!= NULL
)
1107 if (pred
->side_effects
)
1109 pred
= pred
->pred_next
;
1115 /* Return true if there are no predicates with no_default_print in
1116 predicate list PRED, false if there are any.
1117 Returns true if default print should be performed */
1120 default_prints (struct predicate
*pred
)
1122 while (pred
!= NULL
)
1124 if (pred
->no_default_print
)
1126 pred
= pred
->pred_next
;