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 */
58 #if HAVE_SYS_PARAM_H || defined _LIBC
59 # include <sys/param.h>
62 # include <include/sys/stat.h>
64 # include <sys/stat.h>
69 #include "cycle-check.h"
71 #include "unistd-safer.h"
77 # include <inttypes.h>
82 #if ULONG_MAX < ULLONG_MAX
83 # define LONGEST_MODIFIER "ll"
85 # define LONGEST_MODIFIER "l"
91 # define PRIuMAX LONGEST_MODIFIER "u"
96 # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
100 # define NAMLEN(dirent) strlen ((dirent)->d_name)
102 # define dirent direct
103 # define NAMLEN(dirent) (dirent)->d_namlen
105 # include <sys/ndir.h>
108 # include <sys/dir.h>
118 # define close __close
120 # define closedir __closedir
122 # define fchdir __fchdir
126 # define opendir __opendir
128 # define readdir __readdir
130 # undef internal_function
131 # define internal_function /* empty */
134 /* Arrange to make lstat calls go through the wrapper function
135 on systems with an lstat function that does not dereference symlinks
136 that are specified with a trailing slash. */
137 #if ! _LIBC && ! LSTAT_FOLLOWS_SLASHED_SYMLINK
138 int rpl_lstat (const char *, struct stat *);
140 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
144 # define __set_errno(Val) errno = (Val)
147 #ifndef __attribute__
148 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
149 # define __attribute__(x) /* empty */
153 #ifndef ATTRIBUTE_UNUSED
154 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
158 static FTSENT *fts_alloc (FTS *, const char *, size_t) internal_function;
159 static FTSENT *fts_build (FTS *, int) internal_function;
160 static void fts_lfree (FTSENT *) internal_function;
161 static void fts_load (FTS *, FTSENT *) internal_function;
162 static size_t fts_maxarglen (char * const *) internal_function;
163 static void fts_padjust (FTS *, FTSENT *) internal_function;
164 static bool fts_palloc (FTS *, size_t) internal_function;
165 static FTSENT *fts_sort (FTS *, FTSENT *, size_t) internal_function;
166 static unsigned short int fts_stat (FTS *, FTSENT *, bool) internal_function;
167 static int fts_safe_changedir (FTS *, FTSENT *, int, const char *)
171 # define MAX(a,b) ((a) > (b) ? (a) : (b))
175 # define SIZE_MAX ((size_t) -1)
179 # define O_DIRECTORY 0
182 #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
184 #define CLR(opt) (sp->fts_options &= ~(opt))
185 #define ISSET(opt) (sp->fts_options & (opt))
186 #define SET(opt) (sp->fts_options |= (opt))
188 #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
190 /* fts_build flags */
191 #define BCHILD 1 /* fts_children */
192 #define BNAMES 2 /* fts_children, names only */
193 #define BREAD 3 /* fts_read */
195 #define HT_INITIAL_SIZE 31
198 bool fts_debug = false;
200 # define Dprintf(x) do { if (fts_debug) printf x; } while (0)
205 #define ENTER_DIR(Fts, Ent, Tag) \
207 Dprintf ((" %s-entering: %s\n", Tag, (Ent)->fts_path)); \
211 #define LEAVE_DIR(Fts, Ent, Tag) \
213 Dprintf ((" %s-leaving: %s\n", Tag, (Ent)->fts_path)); \
217 /* Use these each of these to map a device/inode pair to an FTSENT. */
226 AD_compare (void const *x, void const *y)
228 struct Active_dir const *ax = x;
229 struct Active_dir const *ay = y;
230 return ax->ino == ay->ino
231 && ax->dev == ay->dev;
235 AD_hash (void const *x, size_t table_size)
237 struct Active_dir const *ax = x;
238 return (uintmax_t) ax->ino % table_size;
242 enter_dir (FTS *fts, FTSENT *ent)
244 if (fts->active_dir_ht)
246 struct stat const *st = ent->fts_statp;
247 struct Active_dir *ad = malloc (sizeof (struct Active_dir));
248 struct Active_dir *ad_from_table;
253 ad->dev = st->st_dev;
254 ad->ino = st->st_ino;
257 /* See if we've already encountered this directory.
258 This can happen when following symlinks as well as
259 with a corrupted directory hierarchy. */
260 ad_from_table = hash_insert (fts->active_dir_ht, ad);
262 if (ad_from_table == NULL)
265 /* Insertion failed due to lack of memory. Free the hash
266 table and turn off this sort of cycle detection. */
267 hash_free (fts->active_dir_ht);
268 fts->active_dir_ht = NULL;
272 if (ad_from_table != ad)
274 /* There was an entry with matching dev/inode already in the table.
275 Record the fact that we've found a cycle. */
276 ent->fts_cycle = ad_from_table->fts_ent;
277 ent->fts_info = FTS_DC;
279 /* ad was not inserted, so free it. */
283 else if (fts->cycle_state)
285 if (cycle_check (fts->cycle_state, ent->fts_statp))
287 /* FIXME: setting fts_cycle like this isn't proper.
288 To do what the documentation requires, we'd have to
289 go around the cycle again and find the right entry.
290 But no callers in coreutils use the fts_cycle member. */
291 ent->fts_cycle = ent;
292 ent->fts_info = FTS_DC;
298 leave_dir (FTS *fts, FTSENT *ent)
300 if (fts->active_dir_ht)
302 struct stat const *st = ent->fts_statp;
303 struct Active_dir obj;
305 obj.dev = st->st_dev;
306 obj.ino = st->st_ino;
307 found = hash_delete (fts->active_dir_ht, &obj);
314 /* Open the directory DIR if possible, and return a file
315 descriptor. Return -1 and set errno on failure. It doesn't matter
316 whether the file descriptor has read or write access. */
320 diropen (char const *dir)
322 int fd = open (dir, O_RDONLY | O_DIRECTORY);
324 fd = open (dir, O_WRONLY | O_DIRECTORY);
329 fts_open (char * const *argv,
330 register int options,
331 int (*compar) (FTSENT const **, FTSENT const **))
334 register FTSENT *p, *root;
335 register size_t nitems;
336 FTSENT *parent, *tmp = NULL; /* pacify gcc */
340 if (options & ~FTS_OPTIONMASK) {
341 __set_errno (EINVAL);
345 /* Allocate/initialize the stream */
346 if ((sp = malloc(sizeof(FTS))) == NULL)
348 memset(sp, 0, sizeof(FTS));
349 sp->fts_compar = compar;
350 sp->fts_options = options;
352 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
353 if (ISSET(FTS_LOGICAL))
357 * Start out with 1K of path space, and enough, in any case,
358 * to hold the user's paths.
361 # define MAXPATHLEN 1024
363 if (! fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
366 /* Allocate/initialize root's parent. */
367 if ((parent = fts_alloc(sp, "", 0)) == NULL)
369 parent->fts_level = FTS_ROOTPARENTLEVEL;
371 /* Allocate/initialize root(s). */
372 for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
373 /* Don't allow zero-length paths. */
374 if ((len = strlen(*argv)) == 0) {
375 __set_errno (ENOENT);
379 if ((p = fts_alloc(sp, *argv, len)) == NULL)
381 p->fts_level = FTS_ROOTLEVEL;
382 p->fts_parent = parent;
383 p->fts_accpath = p->fts_name;
384 p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW) != 0);
386 /* Command-line "." and ".." are real directories. */
387 if (p->fts_info == FTS_DOT)
391 * If comparison routine supplied, traverse in sorted
392 * order; otherwise traverse in the order specified.
407 if (compar && nitems > 1)
408 root = fts_sort(sp, root, nitems);
411 * Allocate a dummy pointer and make fts_read think that we've just
412 * finished the node before the root(s); set p->fts_info to FTS_INIT
413 * so that everything about the "current" node is ignored.
415 if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
417 sp->fts_cur->fts_link = root;
418 sp->fts_cur->fts_info = FTS_INIT;
420 if (ISSET (FTS_TIGHT_CYCLE_CHECK))
422 sp->active_dir_ht = hash_initialize (HT_INITIAL_SIZE,
425 if (sp->active_dir_ht == NULL)
427 sp->cycle_state = malloc (sizeof *sp->cycle_state);
431 sp->cycle_state = malloc (sizeof *sp->cycle_state);
432 if (sp->cycle_state == NULL)
434 cycle_check_init (sp->cycle_state);
435 sp->active_dir_ht = NULL;
439 * If using chdir(2), grab a file descriptor pointing to dot to ensure
440 * that we can get back here; this could be avoided for some paths,
441 * but almost certainly not worth the effort. Slashes, symbolic links,
442 * and ".." are all fairly nasty problems. Note, if we can't get the
443 * descriptor we run anyway, just more slowly.
445 if (!ISSET(FTS_NOCHDIR)
446 && (sp->fts_rfd = diropen (".")) < 0)
451 mem3: fts_lfree(root);
453 mem2: free(sp->fts_path);
460 fts_load (FTS *sp, register FTSENT *p)
466 * Load the stream structure for the next traversal. Since we don't
467 * actually enter the directory until after the preorder visit, set
468 * the fts_accpath field specially so the chdir gets done to the right
469 * place and the user can access the first node. From fts_open it's
470 * known that the path will fit.
472 len = p->fts_pathlen = p->fts_namelen;
473 memmove(sp->fts_path, p->fts_name, len + 1);
474 if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
476 memmove(p->fts_name, cp, len + 1);
477 p->fts_namelen = len;
479 p->fts_accpath = p->fts_path = sp->fts_path;
480 sp->fts_dev = p->fts_statp->st_dev;
486 register FTSENT *freep, *p;
490 * This still works if we haven't read anything -- the dummy structure
491 * points to the root list, so we step through to the end of the root
492 * list which has a valid parent pointer.
495 for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
497 p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
503 /* Free up child linked list, sort array, path buffer. */
505 fts_lfree(sp->fts_child);
510 /* Return to original directory, save errno if necessary. */
511 if (!ISSET(FTS_NOCHDIR)) {
512 if (fchdir(sp->fts_rfd))
514 (void)close(sp->fts_rfd);
517 /* Free any memory used for cycle detection. */
518 if (sp->active_dir_ht)
519 hash_free (sp->active_dir_ht);
521 free (sp->cycle_state);
523 /* Free up the stream pointer. */
526 /* Set errno and return. */
528 __set_errno (saved_errno);
536 * Special case of "/" at the end of the path so that slashes aren't
537 * appended which would cause paths to be written as "....//foo".
540 (p->fts_path[p->fts_pathlen - 1] == '/' \
541 ? p->fts_pathlen - 1 : p->fts_pathlen)
544 fts_read (register FTS *sp)
546 register FTSENT *p, *tmp;
547 register unsigned short int instr;
551 /* If finished or unrecoverable error, return NULL. */
552 if (sp->fts_cur == NULL || ISSET(FTS_STOP))
555 /* Set current node pointer. */
558 /* Save and zero out user instructions. */
559 instr = p->fts_instr;
560 p->fts_instr = FTS_NOINSTR;
562 /* Any type of file may be re-visited; re-stat and re-turn. */
563 if (instr == FTS_AGAIN) {
564 p->fts_info = fts_stat(sp, p, false);
567 Dprintf (("fts_read: p=%s\n",
568 p->fts_info == FTS_INIT ? "" : p->fts_path));
571 * Following a symlink -- SLNONE test allows application to see
572 * SLNONE and recover. If indirecting through a symlink, have
573 * keep a pointer to current location. If unable to get that
574 * pointer, follow fails.
576 if (instr == FTS_FOLLOW &&
577 (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
578 p->fts_info = fts_stat(sp, p, true);
579 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
580 if ((p->fts_symfd = diropen (".")) < 0) {
581 p->fts_errno = errno;
582 p->fts_info = FTS_ERR;
584 p->fts_flags |= FTS_SYMFOLLOW;
586 if (p->fts_info == FTS_D)
587 ENTER_DIR (sp, p, "7");
591 /* Directory in pre-order. */
592 if (p->fts_info == FTS_D) {
593 /* If skipped or crossed mount point, do post-order visit. */
594 if (instr == FTS_SKIP ||
595 (ISSET(FTS_XDEV) && p->fts_statp->st_dev != sp->fts_dev)) {
596 if (p->fts_flags & FTS_SYMFOLLOW)
597 (void)close(p->fts_symfd);
599 fts_lfree(sp->fts_child);
600 sp->fts_child = NULL;
602 p->fts_info = FTS_DP;
603 LEAVE_DIR (sp, p, "1");
607 /* Rebuild if only read the names and now traversing. */
608 if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
610 fts_lfree(sp->fts_child);
611 sp->fts_child = NULL;
615 * Cd to the subdirectory.
617 * If have already read and now fail to chdir, whack the list
618 * to make the names come out right, and set the parent errno
619 * so the application will eventually get an error condition.
620 * Set the FTS_DONTCHDIR flag so that when we logically change
621 * directories back to the parent we don't do a chdir.
623 * If haven't read do so. If the read fails, fts_build sets
624 * FTS_STOP or the fts_info field of the node.
626 if (sp->fts_child != NULL) {
627 if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
628 p->fts_errno = errno;
629 p->fts_flags |= FTS_DONTCHDIR;
630 for (p = sp->fts_child; p != NULL;
633 p->fts_parent->fts_accpath;
635 } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
638 /* If fts_build's call to fts_safe_changedir failed
639 because it was not able to fchdir into a
640 subdirectory, tell the caller. */
642 p->fts_info = FTS_ERR;
643 /* FIXME: see if this should be in an else block */
644 LEAVE_DIR (sp, p, "2");
648 sp->fts_child = NULL;
652 /* Move to the next node on this level. */
654 if ((p = p->fts_link) != NULL) {
658 * If reached the top, return to the original directory (or
659 * the root of the tree), and load the paths for the next root.
661 if (p->fts_level == FTS_ROOTLEVEL) {
662 if (FCHDIR(sp, sp->fts_rfd)) {
667 if (p->fts_info == FTS_D)
668 ENTER_DIR (sp, p, "8");
669 return (sp->fts_cur = p);
673 * User may have called fts_set on the node. If skipped,
674 * ignore. If followed, get a file descriptor so we can
675 * get back if necessary.
677 if (p->fts_instr == FTS_SKIP)
679 if (p->fts_instr == FTS_FOLLOW) {
680 p->fts_info = fts_stat(sp, p, true);
681 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
682 if ((p->fts_symfd = diropen (".")) < 0) {
683 p->fts_errno = errno;
684 p->fts_info = FTS_ERR;
686 p->fts_flags |= FTS_SYMFOLLOW;
688 p->fts_instr = FTS_NOINSTR;
691 name: t = sp->fts_path + NAPPEND(p->fts_parent);
693 memmove(t, p->fts_name, p->fts_namelen + 1);
694 if (p->fts_info == FTS_D)
695 ENTER_DIR (sp, p, "9");
696 return (sp->fts_cur = p);
699 /* Move up to the parent node. */
703 if (p->fts_level == FTS_ROOTPARENTLEVEL) {
705 * Done; free everything up and set errno to 0 so the user
706 * can distinguish between error and EOF.
710 return (sp->fts_cur = NULL);
713 /* NUL terminate the pathname. */
714 sp->fts_path[p->fts_pathlen] = '\0';
717 * Return to the parent directory. If at a root node or came through
718 * a symlink, go back through the file descriptor. Otherwise, cd up
721 if (p->fts_level == FTS_ROOTLEVEL) {
722 if (FCHDIR(sp, sp->fts_rfd)) {
723 p->fts_errno = errno;
726 } else if (p->fts_flags & FTS_SYMFOLLOW) {
727 if (FCHDIR(sp, p->fts_symfd)) {
729 (void)close(p->fts_symfd);
730 __set_errno (saved_errno);
731 p->fts_errno = errno;
734 (void)close(p->fts_symfd);
735 } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
736 fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
737 p->fts_errno = errno;
740 p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
741 if (p->fts_errno == 0)
742 LEAVE_DIR (sp, p, "3");
744 return ISSET(FTS_STOP) ? NULL : p;
748 * Fts_set takes the stream as an argument although it's not used in this
749 * implementation; it would be necessary if anyone wanted to add global
750 * semantics to fts using fts_set. An error return is allowed for similar
755 fts_set(FTS *sp ATTRIBUTE_UNUSED, FTSENT *p, int instr)
757 if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
758 instr != FTS_NOINSTR && instr != FTS_SKIP) {
759 __set_errno (EINVAL);
762 p->fts_instr = instr;
767 fts_children (register FTS *sp, int instr)
772 if (instr != 0 && instr != FTS_NAMEONLY) {
773 __set_errno (EINVAL);
777 /* Set current node pointer. */
781 * Errno set to 0 so user can distinguish empty directory from
786 /* Fatal errors stop here. */
790 /* Return logical hierarchy of user's arguments. */
791 if (p->fts_info == FTS_INIT)
792 return (p->fts_link);
795 * If not a directory being visited in pre-order, stop here. Could
796 * allow FTS_DNR, assuming the user has fixed the problem, but the
797 * same effect is available with FTS_AGAIN.
799 if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
802 /* Free up any previous child list. */
803 if (sp->fts_child != NULL)
804 fts_lfree(sp->fts_child);
806 if (instr == FTS_NAMEONLY) {
813 * If using chdir on a relative path and called BEFORE fts_read does
814 * its chdir to the root of a traversal, we can lose -- we need to
815 * chdir into the subdirectory, and we don't know where the current
816 * directory is, so we can't get back so that the upcoming chdir by
817 * fts_read will work.
819 if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
821 return (sp->fts_child = fts_build(sp, instr));
823 if ((fd = diropen (".")) < 0)
824 return (sp->fts_child = NULL);
825 sp->fts_child = fts_build(sp, instr);
831 return (sp->fts_child);
835 * This is the tricky part -- do not casually change *anything* in here. The
836 * idea is to build the linked list of entries that are used by fts_children
837 * and fts_read. There are lots of special cases.
839 * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
840 * set and it's a physical walk (so that symbolic links can't be directories),
841 * we can do things quickly. First, if it's a 4.4BSD file system, the type
842 * of the file is in the directory entry. Otherwise, we assume that the number
843 * of subdirectories in a node is equal to the number of links to the parent.
844 * The former skips all stat calls. The latter skips stat calls in any leaf
845 * directories and for any files after the subdirectories in the directory have
846 * been found, cutting the stat calls by about 2/3.
850 fts_build (register FTS *sp, int type)
852 register struct dirent *dp;
853 register FTSENT *p, *head;
854 register size_t nitems;
865 size_t len, maxlen, new_len;
868 /* Set current node pointer. */
872 * Open the directory for reading. If this fails, we're done.
873 * If being called from fts_read, set the fts_info field.
875 #if defined FTS_WHITEOUT && 0
876 if (ISSET(FTS_WHITEOUT))
877 oflag = DTF_NODUP|DTF_REWIND;
879 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
881 # define __opendir2(path, flag) opendir(path)
883 if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
885 cur->fts_info = FTS_DNR;
886 cur->fts_errno = errno;
892 * Nlinks is the number of possible entries of type directory in the
893 * directory if we're cheating on stat calls, 0 if we're not doing
894 * any stat calls at all, (nlink_t) -1 if we're statting everything.
896 if (type == BNAMES) {
898 /* Be quiet about nostat, GCC. */
900 } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
901 nlinks = (cur->fts_statp->st_nlink
902 - (ISSET(FTS_SEEDOT) ? 0 : 2));
910 * If we're going to need to stat anything or we want to descend
911 * and stay in the directory, chdir. If this fails we keep going,
912 * but set a flag so we don't chdir after the post-order visit.
913 * We won't be able to stat anything, but we can still return the
914 * names themselves. Note, that since fts_read won't be able to
915 * chdir into the directory, it will have to return different path
916 * names than before, i.e. "a/b" instead of "b". Since the node
917 * has already been visited in pre-order, have to wait until the
918 * post-order visit to return the error. There is a special case
919 * here, if there was nothing to stat then it's not an error to
920 * not be able to stat. This is all fairly nasty. If a program
921 * needed sorted entries or stat information, they had better be
922 * checking FTS_NS on the returned nodes.
925 if (nlinks || type == BREAD) {
926 if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
927 if (nlinks && type == BREAD)
928 cur->fts_errno = errno;
929 cur->fts_flags |= FTS_DONTCHDIR;
940 * Figure out the max file name length that can be stored in the
941 * current path -- the inner loop allocates more path as necessary.
942 * We really wouldn't have to do the maxlen calculations here, we
943 * could do them in fts_read before returning the path, but it's a
944 * lot easier here since the length is part of the dirent structure.
946 * If not changing directories set a pointer so that can just append
947 * each new name into the path.
950 if (ISSET(FTS_NOCHDIR)) {
951 cp = sp->fts_path + len;
954 /* GCC, you're too verbose. */
958 maxlen = sp->fts_pathlen - len;
960 level = cur->fts_level + 1;
962 /* Read the directory, attaching each entry to the `link' pointer. */
964 for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
965 if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
968 if ((p = fts_alloc(sp, dp->d_name, NAMLEN (dp))) == NULL)
970 if (NAMLEN (dp) >= maxlen) {/* include space for NUL */
971 oldaddr = sp->fts_path;
972 if (! fts_palloc(sp, NAMLEN (dp) + len + 1)) {
974 * No more memory for path or structures. Save
975 * errno, free up the current structure and the
976 * structures already allocated.
978 mem1: saved_errno = errno;
983 cur->fts_info = FTS_ERR;
985 __set_errno (saved_errno);
988 /* Did realloc() change the pointer? */
989 if (oldaddr != sp->fts_path) {
991 if (ISSET(FTS_NOCHDIR))
992 cp = sp->fts_path + len;
994 maxlen = sp->fts_pathlen - len;
997 new_len = len + NAMLEN (dp);
1000 * In the unlikely even that we would end up
1001 * with a path longer than SIZE_MAX, free up
1002 * the current structure and the structures already
1003 * allocated, then error out with ENAMETOOLONG.
1008 cur->fts_info = FTS_ERR;
1010 __set_errno (ENAMETOOLONG);
1013 p->fts_level = level;
1014 p->fts_parent = sp->fts_cur;
1015 p->fts_pathlen = new_len;
1017 #if defined FTS_WHITEOUT && 0
1018 if (dp->d_type == DT_WHT)
1019 p->fts_flags |= FTS_ISW;
1024 p->fts_info = FTS_NS;
1025 p->fts_errno = cderrno;
1027 p->fts_info = FTS_NSOK;
1028 p->fts_accpath = cur->fts_accpath;
1029 } else if (nlinks == 0
1030 #if HAVE_STRUCT_DIRENT_D_TYPE
1032 dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
1036 ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
1037 p->fts_info = FTS_NSOK;
1039 /* Build a file name for fts_stat to stat. */
1040 if (ISSET(FTS_NOCHDIR)) {
1041 p->fts_accpath = p->fts_path;
1042 memmove(cp, p->fts_name, p->fts_namelen + 1);
1044 p->fts_accpath = p->fts_name;
1046 p->fts_info = fts_stat(sp, p, false);
1048 /* Decrement link count if applicable. */
1049 if (nlinks > 0 && (p->fts_info == FTS_D ||
1050 p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
1054 /* We walk in directory order so "ls -f" doesn't get upset. */
1068 * If realloc() changed the address of the path, adjust the
1069 * addresses for the rest of the tree and the dir list.
1072 fts_padjust(sp, head);
1075 * If not changing directories, reset the path back to original
1078 if (ISSET(FTS_NOCHDIR)) {
1079 if (len == sp->fts_pathlen || nitems == 0)
1085 * If descended after called from fts_children or after called from
1086 * fts_read and nothing found, get back. At the root level we use
1087 * the saved fd; if one of fts_open()'s arguments is a relative path
1088 * to an empty directory, we wind up here with no other way back. If
1089 * can't get back, we're done.
1091 if (descend && (type == BCHILD || !nitems) &&
1092 (cur->fts_level == FTS_ROOTLEVEL ?
1093 FCHDIR(sp, sp->fts_rfd) :
1094 fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
1095 cur->fts_info = FTS_ERR;
1100 /* If didn't find anything, return NULL. */
1103 cur->fts_info = FTS_DP;
1107 /* Sort the entries. */
1108 if (sp->fts_compar && nitems > 1)
1109 head = fts_sort(sp, head, nitems);
1115 /* Walk ->fts_parent links starting at E_CURR, until the root of the
1116 current hierarchy. There should be a directory with dev/inode
1117 matching those of AD. If not, print a lot of diagnostics. */
1119 find_matching_ancestor (FTSENT const *e_curr, struct Active_dir const *ad)
1122 for (ent = e_curr; ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1124 if (ad->ino == ent->fts_statp->st_ino
1125 && ad->dev == ent->fts_statp->st_dev)
1128 printf ("ERROR: tree dir, %s, not active\n", ad->fts_ent->fts_accpath);
1129 printf ("active dirs:\n");
1131 ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1132 printf (" %s(%"PRIuMAX"/%"PRIuMAX") to %s(%"PRIuMAX"/%"PRIuMAX")...\n",
1133 ad->fts_ent->fts_accpath,
1134 (uintmax_t) ad->dev,
1135 (uintmax_t) ad->ino,
1137 (uintmax_t) ent->fts_statp->st_dev,
1138 (uintmax_t) ent->fts_statp->st_ino);
1142 fts_cross_check (FTS const *sp)
1144 FTSENT const *ent = sp->fts_cur;
1146 if ( ! ISSET (FTS_TIGHT_CYCLE_CHECK))
1149 Dprintf (("fts-cross-check cur=%s\n", ent->fts_path));
1150 /* Make sure every parent dir is in the tree. */
1151 for (t = ent->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1153 struct Active_dir ad;
1154 ad.ino = t->fts_statp->st_ino;
1155 ad.dev = t->fts_statp->st_dev;
1156 if ( ! hash_lookup (sp->active_dir_ht, &ad))
1157 printf ("ERROR: active dir, %s, not in tree\n", t->fts_path);
1160 /* Make sure every dir in the tree is an active dir.
1161 But ENT is not necessarily a directory. If so, just skip this part. */
1162 if (ent->fts_parent->fts_level >= FTS_ROOTLEVEL
1163 && (ent->fts_info == FTS_DP
1164 || ent->fts_info == FTS_D))
1166 struct Active_dir *ad;
1167 for (ad = hash_get_first (sp->active_dir_ht); ad != NULL;
1168 ad = hash_get_next (sp->active_dir_ht, ad))
1170 find_matching_ancestor (ent, ad);
1176 static unsigned short int
1178 fts_stat(FTS *sp, register FTSENT *p, bool follow)
1180 struct stat *sbp = p->fts_statp;
1183 #if defined FTS_WHITEOUT && 0
1184 /* check for whiteout */
1185 if (p->fts_flags & FTS_ISW) {
1186 memset(sbp, '\0', sizeof (*sbp));
1187 sbp->st_mode = S_IFWHT;
1193 * If doing a logical walk, or application requested FTS_FOLLOW, do
1194 * a stat(2). If that fails, check for a non-existent symlink. If
1195 * fail, set the errno from the stat call.
1197 if (ISSET(FTS_LOGICAL) || follow) {
1198 if (stat(p->fts_accpath, sbp)) {
1199 saved_errno = errno;
1200 if (!lstat(p->fts_accpath, sbp)) {
1202 return (FTS_SLNONE);
1204 p->fts_errno = saved_errno;
1207 } else if (lstat(p->fts_accpath, sbp)) {
1208 p->fts_errno = errno;
1209 err: memset(sbp, 0, sizeof(struct stat));
1213 if (S_ISDIR(sbp->st_mode)) {
1214 if (ISDOT(p->fts_name))
1218 if (S_ISLNK(sbp->st_mode))
1220 if (S_ISREG(sbp->st_mode))
1222 return (FTS_DEFAULT);
1226 fts_compar (void const *a, void const *b)
1228 /* Convert A and B to the correct types, to pacify the compiler, and
1229 for portability to bizarre hosts where "void const *" and "FTSENT
1230 const **" differ in runtime representation. The comparison
1231 function cannot modify *a and *b, but there is no compile-time
1233 FTSENT const **pa = (FTSENT const **) a;
1234 FTSENT const **pb = (FTSENT const **) b;
1235 return pa[0]->fts_fts->fts_compar (pa, pb);
1240 fts_sort (FTS *sp, FTSENT *head, register size_t nitems)
1242 register FTSENT **ap, *p;
1244 /* On most modern hosts, void * and FTSENT ** have the same
1245 run-time representation, and one can convert sp->fts_compar to
1246 the type qsort expects without problem. Use the heuristic that
1247 this is OK if the two pointer types are the same size, and if
1248 converting FTSENT ** to long int is the same as converting
1249 FTSENT ** to void * and then to long int. This heuristic isn't
1250 valid in general but we don't know of any counterexamples. */
1252 int (*compare) (void const *, void const *) =
1253 ((sizeof &dummy == sizeof (void *)
1254 && (long int) &dummy == (long int) (void *) &dummy)
1255 ? (int (*) (void const *, void const *)) sp->fts_compar
1259 * Construct an array of pointers to the structures and call qsort(3).
1260 * Reassemble the array in the order returned by qsort. If unable to
1261 * sort for memory reasons, return the directory entries in their
1262 * current order. Allocate enough space for the current needs plus
1263 * 40 so don't realloc one entry at a time.
1265 if (nitems > sp->fts_nitems) {
1268 sp->fts_nitems = nitems + 40;
1269 if (SIZE_MAX / sizeof *a < sp->fts_nitems
1270 || ! (a = realloc (sp->fts_array,
1271 sp->fts_nitems * sizeof *a))) {
1272 free(sp->fts_array);
1273 sp->fts_array = NULL;
1279 for (ap = sp->fts_array, p = head; p; p = p->fts_link)
1281 qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), compare);
1282 for (head = *(ap = sp->fts_array); --nitems; ++ap)
1283 ap[0]->fts_link = ap[1];
1284 ap[0]->fts_link = NULL;
1290 fts_alloc (FTS *sp, const char *name, register size_t namelen)
1296 * The file name is a variable length array. Allocate the FTSENT
1297 * structure and the file name in one chunk.
1299 len = sizeof(FTSENT) + namelen;
1300 if ((p = malloc(len)) == NULL)
1303 /* Copy the name and guarantee NUL termination. */
1304 memmove(p->fts_name, name, namelen);
1305 p->fts_name[namelen] = '\0';
1307 p->fts_namelen = namelen;
1309 p->fts_path = sp->fts_path;
1312 p->fts_instr = FTS_NOINSTR;
1314 p->fts_pointer = NULL;
1320 fts_lfree (register FTSENT *head)
1324 /* Free a linked list of structures. */
1325 while ((p = head)) {
1326 head = head->fts_link;
1332 * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
1333 * Most systems will allow creation of paths much longer than MAXPATHLEN, even
1334 * though the kernel won't resolve them. Add the size (not just what's needed)
1335 * plus 256 bytes so don't realloc the path 2 bytes at a time.
1339 fts_palloc (FTS *sp, size_t more)
1342 size_t new_len = sp->fts_pathlen + more + 256;
1345 * See if fts_pathlen would overflow.
1347 if (new_len < sp->fts_pathlen) {
1350 sp->fts_path = NULL;
1352 sp->fts_path = NULL;
1353 __set_errno (ENAMETOOLONG);
1356 sp->fts_pathlen = new_len;
1357 p = realloc(sp->fts_path, sp->fts_pathlen);
1360 sp->fts_path = NULL;
1368 * When the path is realloc'd, have to fix all of the pointers in structures
1373 fts_padjust (FTS *sp, FTSENT *head)
1376 char *addr = sp->fts_path;
1378 #define ADJUST(p) do { \
1379 if ((p)->fts_accpath != (p)->fts_name) { \
1380 (p)->fts_accpath = \
1381 (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
1383 (p)->fts_path = addr; \
1385 /* Adjust the current set of children. */
1386 for (p = sp->fts_child; p; p = p->fts_link)
1389 /* Adjust the rest of the tree, including the current level. */
1390 for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
1392 p = p->fts_link ? p->fts_link : p->fts_parent;
1398 fts_maxarglen (char * const *argv)
1402 for (max = 0; *argv; ++argv)
1403 if ((len = strlen(*argv)) > max)
1409 * Change to dir specified by fd or path without getting
1410 * tricked by someone changing the world out from underneath us.
1411 * Assumes p->fts_statp->st_dev and p->fts_statp->st_ino are filled in.
1415 fts_safe_changedir (FTS *sp, FTSENT *p, int fd, char const *path)
1417 int ret, oerrno, newfd;
1421 if (ISSET(FTS_NOCHDIR))
1423 if (fd < 0 && (newfd = fd_safer (diropen (path))) < 0)
1425 if (fstat(newfd, &sb)) {
1429 if (p->fts_statp->st_dev != sb.st_dev
1430 || p->fts_statp->st_ino != sb.st_ino) {
1431 __set_errno (ENOENT); /* disinformation */
1435 ret = fchdir(newfd);
1440 __set_errno (oerrno);