1 /* Traverse a file hierarchy.
3 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20 * Copyright (c) 1990, 1993, 1994
21 * The Regents of the University of California. All rights reserved.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 4. Neither the name of the University nor the names of its contributors
32 * may be used to endorse or promote products derived from this software
33 * without specific prior written permission.
35 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 #if defined(LIBC_SCCS) && !defined(lint)
53 static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
54 #endif /* LIBC_SCCS and not lint */
56 #if HAVE_SYS_PARAM_H || defined _LIBC
57 # include <sys/param.h>
60 # include <include/sys/stat.h>
62 # include <sys/stat.h>
69 #include "unistd-safer.h"
74 # include <inttypes.h>
79 #if ULONG_MAX < ULLONG_MAX
80 # define LONGEST_MODIFIER "ll"
82 # define LONGEST_MODIFIER "l"
88 # define PRIuMAX LONGEST_MODIFIER "u"
93 # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
97 # define NAMLEN(dirent) strlen ((dirent)->d_name)
99 # define dirent direct
100 # define NAMLEN(dirent) (dirent)->d_namlen
102 # include <sys/ndir.h>
105 # include <sys/dir.h>
115 # define close __close
117 # define closedir __closedir
119 # define fchdir __fchdir
123 # define opendir __opendir
125 # define readdir __readdir
127 # undef internal_function
128 # define internal_function /* empty */
131 /* Arrange to make lstat calls go through the wrapper function
132 on systems with an lstat function that does not dereference symlinks
133 that are specified with a trailing slash. */
134 #if ! _LIBC && ! LSTAT_FOLLOWS_SLASHED_SYMLINK
135 int rpl_lstat (const char *, struct stat *);
137 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
141 # define __set_errno(Val) errno = (Val)
144 #ifndef __attribute__
145 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
146 # define __attribute__(x) /* empty */
150 #ifndef ATTRIBUTE_UNUSED
151 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
155 static FTSENT *fts_alloc (FTS *, const char *, size_t) internal_function;
156 static FTSENT *fts_build (FTS *, int) internal_function;
157 static void fts_lfree (FTSENT *) internal_function;
158 static void fts_load (FTS *, FTSENT *) internal_function;
159 static size_t fts_maxarglen (char * const *) internal_function;
160 static void fts_padjust (FTS *, FTSENT *) internal_function;
161 static bool fts_palloc (FTS *, size_t) internal_function;
162 static FTSENT *fts_sort (FTS *, FTSENT *, size_t) internal_function;
163 static unsigned short int fts_stat (FTS *, FTSENT *, bool) internal_function;
164 static int fts_safe_changedir (FTS *, FTSENT *, int, const char *)
168 # define MAX(a,b) ((a) > (b) ? (a) : (b))
172 # define SIZE_MAX ((size_t) -1)
176 # define O_DIRECTORY 0
179 #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
181 #define CLR(opt) (sp->fts_options &= ~(opt))
182 #define ISSET(opt) (sp->fts_options & (opt))
183 #define SET(opt) (sp->fts_options |= (opt))
185 #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
187 /* fts_build flags */
188 #define BCHILD 1 /* fts_children */
189 #define BNAMES 2 /* fts_children, names only */
190 #define BREAD 3 /* fts_read */
192 #define HT_INITIAL_SIZE 31
195 bool fts_debug = false;
197 # define Dprintf(x) do { if (fts_debug) printf x; } while (0)
202 #define ENTER_DIR(Fts, Ent, Tag) \
204 Dprintf ((" %s-entering: %s\n", Tag, (Ent)->fts_path)); \
208 #define LEAVE_DIR(Fts, Ent, Tag) \
210 Dprintf ((" %s-leaving: %s\n", Tag, (Ent)->fts_path)); \
214 /* Use these each of these to map a device/inode pair to an FTSENT. */
223 AD_compare (void const *x, void const *y)
225 struct Active_dir const *ax = x;
226 struct Active_dir const *ay = y;
227 return ax->ino == ay->ino
228 && ax->dev == ay->dev;
232 AD_hash (void const *x, size_t table_size)
234 struct Active_dir const *ax = x;
235 return (uintmax_t) ax->ino % table_size;
239 enter_dir (FTS *fts, FTSENT *ent)
241 if (fts->active_dir_ht)
243 struct stat const *st = ent->fts_statp;
244 struct Active_dir *ad = malloc (sizeof (struct Active_dir));
245 struct Active_dir *ad_from_table;
250 ad->dev = st->st_dev;
251 ad->ino = st->st_ino;
254 /* See if we've already encountered this directory.
255 This can happen when following symlinks as well as
256 with a corrupted directory hierarchy. */
257 ad_from_table = hash_insert (fts->active_dir_ht, ad);
259 if (ad_from_table == NULL)
262 /* Insertion failed due to lack of memory. Free the hash
263 table and turn off this sort of cycle detection. */
264 hash_free (fts->active_dir_ht);
265 fts->active_dir_ht = NULL;
269 if (ad_from_table != ad)
271 /* There was an entry with matching dev/inode already in the table.
272 Record the fact that we've found a cycle. */
273 ent->fts_cycle = ad_from_table->fts_ent;
274 ent->fts_info = FTS_DC;
276 /* ad was not inserted, so free it. */
280 else if (fts->cycle_state)
282 if (cycle_check (fts->cycle_state, ent->fts_statp))
284 /* FIXME: setting fts_cycle like this isn't proper.
285 To do what the documentation requires, we'd have to
286 go around the cycle again and find the right entry.
287 But no callers in coreutils use the fts_cycle member. */
288 ent->fts_cycle = ent;
289 ent->fts_info = FTS_DC;
295 leave_dir (FTS *fts, FTSENT *ent)
297 if (fts->active_dir_ht)
299 struct stat const *st = ent->fts_statp;
300 struct Active_dir obj;
302 obj.dev = st->st_dev;
303 obj.ino = st->st_ino;
304 found = hash_delete (fts->active_dir_ht, &obj);
311 /* Open the directory DIR if possible, and return a file
312 descriptor. Return -1 and set errno on failure. It doesn't matter
313 whether the file descriptor has read or write access. */
317 diropen (char const *dir)
319 int fd = open (dir, O_RDONLY | O_DIRECTORY);
321 fd = open (dir, O_WRONLY | O_DIRECTORY);
326 fts_open (char * const *argv,
327 register int options,
328 int (*compar) (FTSENT const **, FTSENT const **))
331 register FTSENT *p, *root;
332 register size_t nitems;
333 FTSENT *parent, *tmp = NULL; /* pacify gcc */
337 if (options & ~FTS_OPTIONMASK) {
338 __set_errno (EINVAL);
342 /* Allocate/initialize the stream */
343 if ((sp = malloc(sizeof(FTS))) == NULL)
345 memset(sp, 0, sizeof(FTS));
346 sp->fts_compar = compar;
347 sp->fts_options = options;
349 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
350 if (ISSET(FTS_LOGICAL))
354 * Start out with 1K of path space, and enough, in any case,
355 * to hold the user's paths.
358 # define MAXPATHLEN 1024
360 if (! fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
363 /* Allocate/initialize root's parent. */
364 if ((parent = fts_alloc(sp, "", 0)) == NULL)
366 parent->fts_level = FTS_ROOTPARENTLEVEL;
368 /* Allocate/initialize root(s). */
369 for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
370 /* Don't allow zero-length paths. */
371 if ((len = strlen(*argv)) == 0) {
372 __set_errno (ENOENT);
376 if ((p = fts_alloc(sp, *argv, len)) == NULL)
378 p->fts_level = FTS_ROOTLEVEL;
379 p->fts_parent = parent;
380 p->fts_accpath = p->fts_name;
381 p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW) != 0);
383 /* Command-line "." and ".." are real directories. */
384 if (p->fts_info == FTS_DOT)
388 * If comparison routine supplied, traverse in sorted
389 * order; otherwise traverse in the order specified.
404 if (compar && nitems > 1)
405 root = fts_sort(sp, root, nitems);
408 * Allocate a dummy pointer and make fts_read think that we've just
409 * finished the node before the root(s); set p->fts_info to FTS_INIT
410 * so that everything about the "current" node is ignored.
412 if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
414 sp->fts_cur->fts_link = root;
415 sp->fts_cur->fts_info = FTS_INIT;
417 if (ISSET (FTS_TIGHT_CYCLE_CHECK))
419 sp->active_dir_ht = hash_initialize (HT_INITIAL_SIZE,
422 if (sp->active_dir_ht == NULL)
424 sp->cycle_state = malloc (sizeof *sp->cycle_state);
428 sp->cycle_state = malloc (sizeof *sp->cycle_state);
429 if (sp->cycle_state == NULL)
431 cycle_check_init (sp->cycle_state);
432 sp->active_dir_ht = NULL;
436 * If using chdir(2), grab a file descriptor pointing to dot to ensure
437 * that we can get back here; this could be avoided for some paths,
438 * but almost certainly not worth the effort. Slashes, symbolic links,
439 * and ".." are all fairly nasty problems. Note, if we can't get the
440 * descriptor we run anyway, just more slowly.
442 if (!ISSET(FTS_NOCHDIR)
443 && (sp->fts_rfd = diropen (".")) < 0)
448 mem3: fts_lfree(root);
450 mem2: free(sp->fts_path);
457 fts_load (FTS *sp, register FTSENT *p)
463 * Load the stream structure for the next traversal. Since we don't
464 * actually enter the directory until after the preorder visit, set
465 * the fts_accpath field specially so the chdir gets done to the right
466 * place and the user can access the first node. From fts_open it's
467 * known that the path will fit.
469 len = p->fts_pathlen = p->fts_namelen;
470 memmove(sp->fts_path, p->fts_name, len + 1);
471 if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
473 memmove(p->fts_name, cp, len + 1);
474 p->fts_namelen = len;
476 p->fts_accpath = p->fts_path = sp->fts_path;
477 sp->fts_dev = p->fts_statp->st_dev;
483 register FTSENT *freep, *p;
487 * This still works if we haven't read anything -- the dummy structure
488 * points to the root list, so we step through to the end of the root
489 * list which has a valid parent pointer.
492 for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
494 p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
500 /* Free up child linked list, sort array, path buffer. */
502 fts_lfree(sp->fts_child);
507 /* Return to original directory, save errno if necessary. */
508 if (!ISSET(FTS_NOCHDIR)) {
509 if (fchdir(sp->fts_rfd))
511 (void)close(sp->fts_rfd);
514 /* Free any memory used for cycle detection. */
515 if (sp->active_dir_ht)
516 hash_free (sp->active_dir_ht);
518 free (sp->cycle_state);
520 /* Free up the stream pointer. */
523 /* Set errno and return. */
525 __set_errno (saved_errno);
533 * Special case of "/" at the end of the path so that slashes aren't
534 * appended which would cause paths to be written as "....//foo".
537 (p->fts_path[p->fts_pathlen - 1] == '/' \
538 ? p->fts_pathlen - 1 : p->fts_pathlen)
541 fts_read (register FTS *sp)
543 register FTSENT *p, *tmp;
544 register unsigned short int instr;
548 /* If finished or unrecoverable error, return NULL. */
549 if (sp->fts_cur == NULL || ISSET(FTS_STOP))
552 /* Set current node pointer. */
555 /* Save and zero out user instructions. */
556 instr = p->fts_instr;
557 p->fts_instr = FTS_NOINSTR;
559 /* Any type of file may be re-visited; re-stat and re-turn. */
560 if (instr == FTS_AGAIN) {
561 p->fts_info = fts_stat(sp, p, false);
564 Dprintf (("fts_read: p=%s\n",
565 p->fts_info == FTS_INIT ? "" : p->fts_path));
568 * Following a symlink -- SLNONE test allows application to see
569 * SLNONE and recover. If indirecting through a symlink, have
570 * keep a pointer to current location. If unable to get that
571 * pointer, follow fails.
573 if (instr == FTS_FOLLOW &&
574 (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
575 p->fts_info = fts_stat(sp, p, true);
576 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
577 if ((p->fts_symfd = diropen (".")) < 0) {
578 p->fts_errno = errno;
579 p->fts_info = FTS_ERR;
581 p->fts_flags |= FTS_SYMFOLLOW;
583 if (p->fts_info == FTS_D)
584 ENTER_DIR (sp, p, "7");
588 /* Directory in pre-order. */
589 if (p->fts_info == FTS_D) {
590 /* If skipped or crossed mount point, do post-order visit. */
591 if (instr == FTS_SKIP ||
592 (ISSET(FTS_XDEV) && p->fts_statp->st_dev != sp->fts_dev)) {
593 if (p->fts_flags & FTS_SYMFOLLOW)
594 (void)close(p->fts_symfd);
596 fts_lfree(sp->fts_child);
597 sp->fts_child = NULL;
599 p->fts_info = FTS_DP;
600 LEAVE_DIR (sp, p, "1");
604 /* Rebuild if only read the names and now traversing. */
605 if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
607 fts_lfree(sp->fts_child);
608 sp->fts_child = NULL;
612 * Cd to the subdirectory.
614 * If have already read and now fail to chdir, whack the list
615 * to make the names come out right, and set the parent errno
616 * so the application will eventually get an error condition.
617 * Set the FTS_DONTCHDIR flag so that when we logically change
618 * directories back to the parent we don't do a chdir.
620 * If haven't read do so. If the read fails, fts_build sets
621 * FTS_STOP or the fts_info field of the node.
623 if (sp->fts_child != NULL) {
624 if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
625 p->fts_errno = errno;
626 p->fts_flags |= FTS_DONTCHDIR;
627 for (p = sp->fts_child; p != NULL;
630 p->fts_parent->fts_accpath;
632 } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
635 /* If fts_build's call to fts_safe_changedir failed
636 because it was not able to fchdir into a
637 subdirectory, tell the caller. */
639 p->fts_info = FTS_ERR;
640 /* FIXME: see if this should be in an else block */
641 LEAVE_DIR (sp, p, "2");
645 sp->fts_child = NULL;
649 /* Move to the next node on this level. */
651 if ((p = p->fts_link) != NULL) {
655 * If reached the top, return to the original directory (or
656 * the root of the tree), and load the paths for the next root.
658 if (p->fts_level == FTS_ROOTLEVEL) {
659 if (FCHDIR(sp, sp->fts_rfd)) {
664 if (p->fts_info == FTS_D)
665 ENTER_DIR (sp, p, "8");
666 return (sp->fts_cur = p);
670 * User may have called fts_set on the node. If skipped,
671 * ignore. If followed, get a file descriptor so we can
672 * get back if necessary.
674 if (p->fts_instr == FTS_SKIP)
676 if (p->fts_instr == FTS_FOLLOW) {
677 p->fts_info = fts_stat(sp, p, true);
678 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
679 if ((p->fts_symfd = diropen (".")) < 0) {
680 p->fts_errno = errno;
681 p->fts_info = FTS_ERR;
683 p->fts_flags |= FTS_SYMFOLLOW;
685 p->fts_instr = FTS_NOINSTR;
688 name: t = sp->fts_path + NAPPEND(p->fts_parent);
690 memmove(t, p->fts_name, p->fts_namelen + 1);
691 if (p->fts_info == FTS_D)
692 ENTER_DIR (sp, p, "9");
693 return (sp->fts_cur = p);
696 /* Move up to the parent node. */
700 if (p->fts_level == FTS_ROOTPARENTLEVEL) {
702 * Done; free everything up and set errno to 0 so the user
703 * can distinguish between error and EOF.
707 return (sp->fts_cur = NULL);
710 /* NUL terminate the pathname. */
711 sp->fts_path[p->fts_pathlen] = '\0';
714 * Return to the parent directory. If at a root node or came through
715 * a symlink, go back through the file descriptor. Otherwise, cd up
718 if (p->fts_level == FTS_ROOTLEVEL) {
719 if (FCHDIR(sp, sp->fts_rfd)) {
720 p->fts_errno = errno;
723 } else if (p->fts_flags & FTS_SYMFOLLOW) {
724 if (FCHDIR(sp, p->fts_symfd)) {
726 (void)close(p->fts_symfd);
727 __set_errno (saved_errno);
728 p->fts_errno = errno;
731 (void)close(p->fts_symfd);
732 } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
733 fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
734 p->fts_errno = errno;
737 p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
738 if (p->fts_errno == 0)
739 LEAVE_DIR (sp, p, "3");
741 return ISSET(FTS_STOP) ? NULL : p;
745 * Fts_set takes the stream as an argument although it's not used in this
746 * implementation; it would be necessary if anyone wanted to add global
747 * semantics to fts using fts_set. An error return is allowed for similar
752 fts_set(FTS *sp ATTRIBUTE_UNUSED, FTSENT *p, int instr)
754 if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
755 instr != FTS_NOINSTR && instr != FTS_SKIP) {
756 __set_errno (EINVAL);
759 p->fts_instr = instr;
764 fts_children (register FTS *sp, int instr)
769 if (instr != 0 && instr != FTS_NAMEONLY) {
770 __set_errno (EINVAL);
774 /* Set current node pointer. */
778 * Errno set to 0 so user can distinguish empty directory from
783 /* Fatal errors stop here. */
787 /* Return logical hierarchy of user's arguments. */
788 if (p->fts_info == FTS_INIT)
789 return (p->fts_link);
792 * If not a directory being visited in pre-order, stop here. Could
793 * allow FTS_DNR, assuming the user has fixed the problem, but the
794 * same effect is available with FTS_AGAIN.
796 if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
799 /* Free up any previous child list. */
800 if (sp->fts_child != NULL)
801 fts_lfree(sp->fts_child);
803 if (instr == FTS_NAMEONLY) {
810 * If using chdir on a relative path and called BEFORE fts_read does
811 * its chdir to the root of a traversal, we can lose -- we need to
812 * chdir into the subdirectory, and we don't know where the current
813 * directory is, so we can't get back so that the upcoming chdir by
814 * fts_read will work.
816 if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
818 return (sp->fts_child = fts_build(sp, instr));
820 if ((fd = diropen (".")) < 0)
821 return (sp->fts_child = NULL);
822 sp->fts_child = fts_build(sp, instr);
828 return (sp->fts_child);
832 * This is the tricky part -- do not casually change *anything* in here. The
833 * idea is to build the linked list of entries that are used by fts_children
834 * and fts_read. There are lots of special cases.
836 * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
837 * set and it's a physical walk (so that symbolic links can't be directories),
838 * we can do things quickly. First, if it's a 4.4BSD file system, the type
839 * of the file is in the directory entry. Otherwise, we assume that the number
840 * of subdirectories in a node is equal to the number of links to the parent.
841 * The former skips all stat calls. The latter skips stat calls in any leaf
842 * directories and for any files after the subdirectories in the directory have
843 * been found, cutting the stat calls by about 2/3.
847 fts_build (register FTS *sp, int type)
849 register struct dirent *dp;
850 register FTSENT *p, *head;
851 register size_t nitems;
862 size_t len, maxlen, new_len;
865 /* Set current node pointer. */
869 * Open the directory for reading. If this fails, we're done.
870 * If being called from fts_read, set the fts_info field.
872 #if defined FTS_WHITEOUT && 0
873 if (ISSET(FTS_WHITEOUT))
874 oflag = DTF_NODUP|DTF_REWIND;
876 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
878 # define __opendir2(path, flag) opendir(path)
880 if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
882 cur->fts_info = FTS_DNR;
883 cur->fts_errno = errno;
889 * Nlinks is the number of possible entries of type directory in the
890 * directory if we're cheating on stat calls, 0 if we're not doing
891 * any stat calls at all, (nlink_t) -1 if we're statting everything.
893 if (type == BNAMES) {
895 /* Be quiet about nostat, GCC. */
897 } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
898 nlinks = (cur->fts_statp->st_nlink
899 - (ISSET(FTS_SEEDOT) ? 0 : 2));
907 * If we're going to need to stat anything or we want to descend
908 * and stay in the directory, chdir. If this fails we keep going,
909 * but set a flag so we don't chdir after the post-order visit.
910 * We won't be able to stat anything, but we can still return the
911 * names themselves. Note, that since fts_read won't be able to
912 * chdir into the directory, it will have to return different path
913 * names than before, i.e. "a/b" instead of "b". Since the node
914 * has already been visited in pre-order, have to wait until the
915 * post-order visit to return the error. There is a special case
916 * here, if there was nothing to stat then it's not an error to
917 * not be able to stat. This is all fairly nasty. If a program
918 * needed sorted entries or stat information, they had better be
919 * checking FTS_NS on the returned nodes.
922 if (nlinks || type == BREAD) {
923 if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
924 if (nlinks && type == BREAD)
925 cur->fts_errno = errno;
926 cur->fts_flags |= FTS_DONTCHDIR;
929 (void)closedir(dirp);
937 * Figure out the max file name length that can be stored in the
938 * current path -- the inner loop allocates more path as necessary.
939 * We really wouldn't have to do the maxlen calculations here, we
940 * could do them in fts_read before returning the path, but it's a
941 * lot easier here since the length is part of the dirent structure.
943 * If not changing directories set a pointer so that can just append
944 * each new name into the path.
947 if (ISSET(FTS_NOCHDIR)) {
948 cp = sp->fts_path + len;
951 /* GCC, you're too verbose. */
955 maxlen = sp->fts_pathlen - len;
957 level = cur->fts_level + 1;
959 /* Read the directory, attaching each entry to the `link' pointer. */
961 for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
962 if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
965 if ((p = fts_alloc(sp, dp->d_name, NAMLEN (dp))) == NULL)
967 if (NAMLEN (dp) >= maxlen) {/* include space for NUL */
968 oldaddr = sp->fts_path;
969 if (! fts_palloc(sp, NAMLEN (dp) + len + 1)) {
971 * No more memory for path or structures. Save
972 * errno, free up the current structure and the
973 * structures already allocated.
975 mem1: saved_errno = errno;
979 (void)closedir(dirp);
980 cur->fts_info = FTS_ERR;
982 __set_errno (saved_errno);
985 /* Did realloc() change the pointer? */
986 if (oldaddr != sp->fts_path) {
988 if (ISSET(FTS_NOCHDIR))
989 cp = sp->fts_path + len;
991 maxlen = sp->fts_pathlen - len;
994 new_len = len + NAMLEN (dp);
997 * In the unlikely even that we would end up
998 * with a path longer than SIZE_MAX, free up
999 * the current structure and the structures already
1000 * allocated, then error out with ENAMETOOLONG.
1004 (void)closedir(dirp);
1005 cur->fts_info = FTS_ERR;
1007 __set_errno (ENAMETOOLONG);
1010 p->fts_level = level;
1011 p->fts_parent = sp->fts_cur;
1012 p->fts_pathlen = new_len;
1014 #if defined FTS_WHITEOUT && 0
1015 if (dp->d_type == DT_WHT)
1016 p->fts_flags |= FTS_ISW;
1021 p->fts_info = FTS_NS;
1022 p->fts_errno = cderrno;
1024 p->fts_info = FTS_NSOK;
1025 p->fts_accpath = cur->fts_accpath;
1026 } else if (nlinks == 0
1027 #if HAVE_STRUCT_DIRENT_D_TYPE
1029 dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
1033 ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
1034 p->fts_info = FTS_NSOK;
1036 /* Build a file name for fts_stat to stat. */
1037 if (ISSET(FTS_NOCHDIR)) {
1038 p->fts_accpath = p->fts_path;
1039 memmove(cp, p->fts_name, p->fts_namelen + 1);
1041 p->fts_accpath = p->fts_name;
1043 p->fts_info = fts_stat(sp, p, false);
1045 /* Decrement link count if applicable. */
1047 && (TYPE_SIGNED (nlink_t) || nostat)
1048 && (p->fts_info == FTS_D ||
1049 p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
1053 /* We walk in directory order so "ls -f" doesn't get upset. */
1064 (void)closedir(dirp);
1067 * If realloc() changed the address of the path, adjust the
1068 * addresses for the rest of the tree and the dir list.
1071 fts_padjust(sp, head);
1074 * If not changing directories, reset the path back to original
1077 if (ISSET(FTS_NOCHDIR)) {
1078 if (len == sp->fts_pathlen || nitems == 0)
1084 * If descended after called from fts_children or after called from
1085 * fts_read and nothing found, get back. At the root level we use
1086 * the saved fd; if one of fts_open()'s arguments is a relative path
1087 * to an empty directory, we wind up here with no other way back. If
1088 * can't get back, we're done.
1090 if (descend && (type == BCHILD || !nitems) &&
1091 (cur->fts_level == FTS_ROOTLEVEL ?
1092 FCHDIR(sp, sp->fts_rfd) :
1093 fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
1094 cur->fts_info = FTS_ERR;
1099 /* If didn't find anything, return NULL. */
1102 cur->fts_info = FTS_DP;
1106 /* Sort the entries. */
1107 if (sp->fts_compar && nitems > 1)
1108 head = fts_sort(sp, head, nitems);
1114 /* Walk ->fts_parent links starting at E_CURR, until the root of the
1115 current hierarchy. There should be a directory with dev/inode
1116 matching those of AD. If not, print a lot of diagnostics. */
1118 find_matching_ancestor (FTSENT const *e_curr, struct Active_dir const *ad)
1121 for (ent = e_curr; ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1123 if (ad->ino == ent->fts_statp->st_ino
1124 && ad->dev == ent->fts_statp->st_dev)
1127 printf ("ERROR: tree dir, %s, not active\n", ad->fts_ent->fts_accpath);
1128 printf ("active dirs:\n");
1130 ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1131 printf (" %s(%"PRIuMAX"/%"PRIuMAX") to %s(%"PRIuMAX"/%"PRIuMAX")...\n",
1132 ad->fts_ent->fts_accpath,
1133 (uintmax_t) ad->dev,
1134 (uintmax_t) ad->ino,
1136 (uintmax_t) ent->fts_statp->st_dev,
1137 (uintmax_t) ent->fts_statp->st_ino);
1141 fts_cross_check (FTS const *sp)
1143 FTSENT const *ent = sp->fts_cur;
1145 if ( ! ISSET (FTS_TIGHT_CYCLE_CHECK))
1148 Dprintf (("fts-cross-check cur=%s\n", ent->fts_path));
1149 /* Make sure every parent dir is in the tree. */
1150 for (t = ent->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1152 struct Active_dir ad;
1153 ad.ino = t->fts_statp->st_ino;
1154 ad.dev = t->fts_statp->st_dev;
1155 if ( ! hash_lookup (sp->active_dir_ht, &ad))
1156 printf ("ERROR: active dir, %s, not in tree\n", t->fts_path);
1159 /* Make sure every dir in the tree is an active dir.
1160 But ENT is not necessarily a directory. If so, just skip this part. */
1161 if (ent->fts_parent->fts_level >= FTS_ROOTLEVEL
1162 && (ent->fts_info == FTS_DP
1163 || ent->fts_info == FTS_D))
1165 struct Active_dir *ad;
1166 for (ad = hash_get_first (sp->active_dir_ht); ad != NULL;
1167 ad = hash_get_next (sp->active_dir_ht, ad))
1169 find_matching_ancestor (ent, ad);
1175 static unsigned short int
1177 fts_stat(FTS *sp, register FTSENT *p, bool follow)
1179 struct stat *sbp = p->fts_statp;
1182 #if defined FTS_WHITEOUT && 0
1183 /* check for whiteout */
1184 if (p->fts_flags & FTS_ISW) {
1185 memset(sbp, '\0', sizeof (*sbp));
1186 sbp->st_mode = S_IFWHT;
1192 * If doing a logical walk, or application requested FTS_FOLLOW, do
1193 * a stat(2). If that fails, check for a non-existent symlink. If
1194 * fail, set the errno from the stat call.
1196 if (ISSET(FTS_LOGICAL) || follow) {
1197 if (stat(p->fts_accpath, sbp)) {
1198 saved_errno = errno;
1199 if (!lstat(p->fts_accpath, sbp)) {
1201 return (FTS_SLNONE);
1203 p->fts_errno = saved_errno;
1206 } else if (lstat(p->fts_accpath, sbp)) {
1207 p->fts_errno = errno;
1208 err: memset(sbp, 0, sizeof(struct stat));
1212 if (S_ISDIR(sbp->st_mode)) {
1213 if (ISDOT(p->fts_name))
1217 if (S_ISLNK(sbp->st_mode))
1219 if (S_ISREG(sbp->st_mode))
1221 return (FTS_DEFAULT);
1225 fts_compar (void const *a, void const *b)
1227 /* Convert A and B to the correct types, to pacify the compiler, and
1228 for portability to bizarre hosts where "void const *" and "FTSENT
1229 const **" differ in runtime representation. The comparison
1230 function cannot modify *a and *b, but there is no compile-time
1232 FTSENT const **pa = (FTSENT const **) a;
1233 FTSENT const **pb = (FTSENT const **) b;
1234 return pa[0]->fts_fts->fts_compar (pa, pb);
1239 fts_sort (FTS *sp, FTSENT *head, register size_t nitems)
1241 register FTSENT **ap, *p;
1243 /* On most modern hosts, void * and FTSENT ** have the same
1244 run-time representation, and one can convert sp->fts_compar to
1245 the type qsort expects without problem. Use the heuristic that
1246 this is OK if the two pointer types are the same size, and if
1247 converting FTSENT ** to long int is the same as converting
1248 FTSENT ** to void * and then to long int. This heuristic isn't
1249 valid in general but we don't know of any counterexamples. */
1251 int (*compare) (void const *, void const *) =
1252 ((sizeof &dummy == sizeof (void *)
1253 && (long int) &dummy == (long int) (void *) &dummy)
1254 ? (int (*) (void const *, void const *)) sp->fts_compar
1258 * Construct an array of pointers to the structures and call qsort(3).
1259 * Reassemble the array in the order returned by qsort. If unable to
1260 * sort for memory reasons, return the directory entries in their
1261 * current order. Allocate enough space for the current needs plus
1262 * 40 so don't realloc one entry at a time.
1264 if (nitems > sp->fts_nitems) {
1267 sp->fts_nitems = nitems + 40;
1268 if (SIZE_MAX / sizeof *a < sp->fts_nitems
1269 || ! (a = realloc (sp->fts_array,
1270 sp->fts_nitems * sizeof *a))) {
1271 free(sp->fts_array);
1272 sp->fts_array = NULL;
1278 for (ap = sp->fts_array, p = head; p; p = p->fts_link)
1280 qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), compare);
1281 for (head = *(ap = sp->fts_array); --nitems; ++ap)
1282 ap[0]->fts_link = ap[1];
1283 ap[0]->fts_link = NULL;
1289 fts_alloc (FTS *sp, const char *name, register size_t namelen)
1295 * The file name is a variable length array. Allocate the FTSENT
1296 * structure and the file name in one chunk.
1298 len = sizeof(FTSENT) + namelen;
1299 if ((p = malloc(len)) == NULL)
1302 /* Copy the name and guarantee NUL termination. */
1303 memmove(p->fts_name, name, namelen);
1304 p->fts_name[namelen] = '\0';
1306 p->fts_namelen = namelen;
1308 p->fts_path = sp->fts_path;
1311 p->fts_instr = FTS_NOINSTR;
1313 p->fts_pointer = NULL;
1319 fts_lfree (register FTSENT *head)
1323 /* Free a linked list of structures. */
1324 while ((p = head)) {
1325 head = head->fts_link;
1331 * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
1332 * Most systems will allow creation of paths much longer than MAXPATHLEN, even
1333 * though the kernel won't resolve them. Add the size (not just what's needed)
1334 * plus 256 bytes so don't realloc the path 2 bytes at a time.
1338 fts_palloc (FTS *sp, size_t more)
1341 size_t new_len = sp->fts_pathlen + more + 256;
1344 * See if fts_pathlen would overflow.
1346 if (new_len < sp->fts_pathlen) {
1349 sp->fts_path = NULL;
1351 sp->fts_path = NULL;
1352 __set_errno (ENAMETOOLONG);
1355 sp->fts_pathlen = new_len;
1356 p = realloc(sp->fts_path, sp->fts_pathlen);
1359 sp->fts_path = NULL;
1367 * When the path is realloc'd, have to fix all of the pointers in structures
1372 fts_padjust (FTS *sp, FTSENT *head)
1375 char *addr = sp->fts_path;
1377 #define ADJUST(p) do { \
1378 if ((p)->fts_accpath != (p)->fts_name) { \
1379 (p)->fts_accpath = \
1380 (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
1382 (p)->fts_path = addr; \
1384 /* Adjust the current set of children. */
1385 for (p = sp->fts_child; p; p = p->fts_link)
1388 /* Adjust the rest of the tree, including the current level. */
1389 for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
1391 p = p->fts_link ? p->fts_link : p->fts_parent;
1397 fts_maxarglen (char * const *argv)
1401 for (max = 0; *argv; ++argv)
1402 if ((len = strlen(*argv)) > max)
1408 * Change to dir specified by fd or path without getting
1409 * tricked by someone changing the world out from underneath us.
1410 * Assumes p->fts_statp->st_dev and p->fts_statp->st_ino are filled in.
1414 fts_safe_changedir (FTS *sp, FTSENT *p, int fd, char const *path)
1416 int ret, oerrno, newfd;
1420 if (ISSET(FTS_NOCHDIR))
1422 if (fd < 0 && (newfd = fd_safer (diropen (path))) < 0)
1424 if (fstat(newfd, &sb)) {
1428 if (p->fts_statp->st_dev != sb.st_dev
1429 || p->fts_statp->st_ino != sb.st_ino) {
1430 __set_errno (ENOENT); /* disinformation */
1434 ret = fchdir(newfd);
1439 __set_errno (oerrno);