1 /* Traverse a file hierarchy.
3 Copyright (C) 2004, 2005, 2006 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>
80 # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
84 # define NAMLEN(dirent) strlen ((dirent)->d_name)
86 # define dirent direct
87 # define NAMLEN(dirent) (dirent)->d_namlen
89 # include <sys/ndir.h>
102 # define close __close
104 # define closedir __closedir
106 # define fchdir __fchdir
110 # define opendir __opendir
112 # define readdir __readdir
114 # undef internal_function
115 # define internal_function /* empty */
119 # define __set_errno(Val) errno = (Val)
122 #ifndef __attribute__
123 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
124 # define __attribute__(x) /* empty */
128 #ifndef ATTRIBUTE_UNUSED
129 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
133 static FTSENT *fts_alloc (FTS *, const char *, size_t) internal_function;
134 static FTSENT *fts_build (FTS *, int) internal_function;
135 static void fts_lfree (FTSENT *) internal_function;
136 static void fts_load (FTS *, FTSENT *) internal_function;
137 static size_t fts_maxarglen (char * const *) internal_function;
138 static void fts_padjust (FTS *, FTSENT *) internal_function;
139 static bool fts_palloc (FTS *, size_t) internal_function;
140 static FTSENT *fts_sort (FTS *, FTSENT *, size_t) internal_function;
141 static unsigned short int fts_stat (FTS *, FTSENT *, bool) internal_function;
142 static int fts_safe_changedir (FTS *, FTSENT *, int, const char *)
146 static bool enter_dir (FTS *fts, FTSENT *ent) { return true; }
147 static void leave_dir (FTS *fts, FTSENT *ent) {}
148 static bool setup_dir (FTS *fts) { return true; }
149 static void free_dir (FTS *fts) {}
151 # include "fcntl--.h"
152 # include "fts-cycle.c"
156 # define MAX(a,b) ((a) > (b) ? (a) : (b))
160 # define SIZE_MAX ((size_t) -1)
164 # define O_DIRECTORY 0
167 #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
169 #define CLR(opt) (sp->fts_options &= ~(opt))
170 #define ISSET(opt) (sp->fts_options & (opt))
171 #define SET(opt) (sp->fts_options |= (opt))
173 #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
175 /* fts_build flags */
176 #define BCHILD 1 /* fts_children */
177 #define BNAMES 2 /* fts_children, names only */
178 #define BREAD 3 /* fts_read */
181 # include <inttypes.h>
184 bool fts_debug = false;
185 # define Dprintf(x) do { if (fts_debug) printf x; } while (0)
190 #define LEAVE_DIR(Fts, Ent, Tag) \
193 Dprintf ((" %s-leaving: %s\n", Tag, (Ent)->fts_path)); \
194 leave_dir (Fts, Ent); \
198 /* Open the directory DIR if possible, and return a file
199 descriptor. Return -1 and set errno on failure. It doesn't matter
200 whether the file descriptor has read or write access. */
204 diropen (char const *dir)
206 return open (dir, O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
210 fts_open (char * const *argv,
211 register int options,
212 int (*compar) (FTSENT const **, FTSENT const **))
215 register FTSENT *p, *root;
216 register size_t nitems;
217 FTSENT *parent, *tmp = NULL; /* pacify gcc */
221 if (options & ~FTS_OPTIONMASK) {
222 __set_errno (EINVAL);
226 /* Allocate/initialize the stream */
227 if ((sp = malloc(sizeof(FTS))) == NULL)
229 memset(sp, 0, sizeof(FTS));
230 sp->fts_compar = compar;
231 sp->fts_options = options;
233 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
234 if (ISSET(FTS_LOGICAL))
238 * Start out with 1K of file name space, and enough, in any case,
239 * to hold the user's file names.
242 # define MAXPATHLEN 1024
244 size_t maxarglen = fts_maxarglen(argv);
245 if (! fts_palloc(sp, MAX(maxarglen, MAXPATHLEN)))
248 /* Allocate/initialize root's parent. */
249 if ((parent = fts_alloc(sp, "", 0)) == NULL)
251 parent->fts_level = FTS_ROOTPARENTLEVEL;
253 /* Allocate/initialize root(s). */
254 for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
255 /* Don't allow zero-length file names. */
256 if ((len = strlen(*argv)) == 0) {
257 __set_errno (ENOENT);
261 if ((p = fts_alloc(sp, *argv, len)) == NULL)
263 p->fts_level = FTS_ROOTLEVEL;
264 p->fts_parent = parent;
265 p->fts_accpath = p->fts_name;
266 p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW) != 0);
268 /* Command-line "." and ".." are real directories. */
269 if (p->fts_info == FTS_DOT)
273 * If comparison routine supplied, traverse in sorted
274 * order; otherwise traverse in the order specified.
289 if (compar && nitems > 1)
290 root = fts_sort(sp, root, nitems);
293 * Allocate a dummy pointer and make fts_read think that we've just
294 * finished the node before the root(s); set p->fts_info to FTS_INIT
295 * so that everything about the "current" node is ignored.
297 if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
299 sp->fts_cur->fts_link = root;
300 sp->fts_cur->fts_info = FTS_INIT;
301 if (! setup_dir (sp))
305 * If using chdir(2), grab a file descriptor pointing to dot to ensure
306 * that we can get back here; this could be avoided for some file names,
307 * but almost certainly not worth the effort. Slashes, symbolic links,
308 * and ".." are all fairly nasty problems. Note, if we can't get the
309 * descriptor we run anyway, just more slowly.
311 if (!ISSET(FTS_NOCHDIR)
312 && (sp->fts_rfd = diropen (".")) < 0)
317 mem3: fts_lfree(root);
319 mem2: free(sp->fts_path);
326 fts_load (FTS *sp, register FTSENT *p)
332 * Load the stream structure for the next traversal. Since we don't
333 * actually enter the directory until after the preorder visit, set
334 * the fts_accpath field specially so the chdir gets done to the right
335 * place and the user can access the first node. From fts_open it's
336 * known that the file name will fit.
338 len = p->fts_pathlen = p->fts_namelen;
339 memmove(sp->fts_path, p->fts_name, len + 1);
340 if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
342 memmove(p->fts_name, cp, len + 1);
343 p->fts_namelen = len;
345 p->fts_accpath = p->fts_path = sp->fts_path;
346 sp->fts_dev = p->fts_statp->st_dev;
352 register FTSENT *freep, *p;
356 * This still works if we haven't read anything -- the dummy structure
357 * points to the root list, so we step through to the end of the root
358 * list which has a valid parent pointer.
361 for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
363 p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
369 /* Free up child linked list, sort array, file name buffer. */
371 fts_lfree(sp->fts_child);
376 /* Return to original directory, save errno if necessary. */
377 if (!ISSET(FTS_NOCHDIR)) {
378 if (fchdir(sp->fts_rfd))
380 (void)close(sp->fts_rfd);
385 /* Free up the stream pointer. */
388 /* Set errno and return. */
390 __set_errno (saved_errno);
398 * Special case of "/" at the end of the file name so that slashes aren't
399 * appended which would cause file names to be written as "....//foo".
402 (p->fts_path[p->fts_pathlen - 1] == '/' \
403 ? p->fts_pathlen - 1 : p->fts_pathlen)
406 fts_read (register FTS *sp)
408 register FTSENT *p, *tmp;
409 register unsigned short int instr;
413 /* If finished or unrecoverable error, return NULL. */
414 if (sp->fts_cur == NULL || ISSET(FTS_STOP))
417 /* Set current node pointer. */
420 /* Save and zero out user instructions. */
421 instr = p->fts_instr;
422 p->fts_instr = FTS_NOINSTR;
424 /* Any type of file may be re-visited; re-stat and re-turn. */
425 if (instr == FTS_AGAIN) {
426 p->fts_info = fts_stat(sp, p, false);
429 Dprintf (("fts_read: p=%s\n",
430 p->fts_info == FTS_INIT ? "" : p->fts_path));
433 * Following a symlink -- SLNONE test allows application to see
434 * SLNONE and recover. If indirecting through a symlink, have
435 * keep a pointer to current location. If unable to get that
436 * pointer, follow fails.
438 if (instr == FTS_FOLLOW &&
439 (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
440 p->fts_info = fts_stat(sp, p, true);
441 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
442 if ((p->fts_symfd = diropen (".")) < 0) {
443 p->fts_errno = errno;
444 p->fts_info = FTS_ERR;
446 p->fts_flags |= FTS_SYMFOLLOW;
451 /* Directory in pre-order. */
452 if (p->fts_info == FTS_D) {
453 /* If skipped or crossed mount point, do post-order visit. */
454 if (instr == FTS_SKIP ||
455 (ISSET(FTS_XDEV) && p->fts_statp->st_dev != sp->fts_dev)) {
456 if (p->fts_flags & FTS_SYMFOLLOW)
457 (void)close(p->fts_symfd);
459 fts_lfree(sp->fts_child);
460 sp->fts_child = NULL;
462 p->fts_info = FTS_DP;
463 LEAVE_DIR (sp, p, "1");
467 /* Rebuild if only read the names and now traversing. */
468 if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
470 fts_lfree(sp->fts_child);
471 sp->fts_child = NULL;
475 * Cd to the subdirectory.
477 * If have already read and now fail to chdir, whack the list
478 * to make the names come out right, and set the parent errno
479 * so the application will eventually get an error condition.
480 * Set the FTS_DONTCHDIR flag so that when we logically change
481 * directories back to the parent we don't do a chdir.
483 * If haven't read do so. If the read fails, fts_build sets
484 * FTS_STOP or the fts_info field of the node.
486 if (sp->fts_child != NULL) {
487 if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
488 p->fts_errno = errno;
489 p->fts_flags |= FTS_DONTCHDIR;
490 for (p = sp->fts_child; p != NULL;
493 p->fts_parent->fts_accpath;
495 } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
498 /* If fts_build's call to fts_safe_changedir failed
499 because it was not able to fchdir into a
500 subdirectory, tell the caller. */
502 p->fts_info = FTS_ERR;
503 /* FIXME: see if this should be in an else block */
504 LEAVE_DIR (sp, p, "2");
508 sp->fts_child = NULL;
512 /* Move to the next node on this level. */
514 if ((p = p->fts_link) != NULL) {
518 * If reached the top, return to the original directory (or
519 * the root of the tree), and load the file names for the next
522 if (p->fts_level == FTS_ROOTLEVEL) {
523 if (FCHDIR(sp, sp->fts_rfd)) {
533 * User may have called fts_set on the node. If skipped,
534 * ignore. If followed, get a file descriptor so we can
535 * get back if necessary.
537 if (p->fts_instr == FTS_SKIP)
539 if (p->fts_instr == FTS_FOLLOW) {
540 p->fts_info = fts_stat(sp, p, true);
541 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
542 if ((p->fts_symfd = diropen (".")) < 0) {
543 p->fts_errno = errno;
544 p->fts_info = FTS_ERR;
546 p->fts_flags |= FTS_SYMFOLLOW;
548 p->fts_instr = FTS_NOINSTR;
551 name: t = sp->fts_path + NAPPEND(p->fts_parent);
553 memmove(t, p->fts_name, p->fts_namelen + 1);
556 if (p->fts_info == FTS_D)
558 Dprintf ((" %s-entering: %s\n", sp, p->fts_path));
559 if (! enter_dir (sp, p))
561 __set_errno (ENOMEM);
568 /* Move up to the parent node. */
572 if (p->fts_level == FTS_ROOTPARENTLEVEL) {
574 * Done; free everything up and set errno to 0 so the user
575 * can distinguish between error and EOF.
579 return (sp->fts_cur = NULL);
582 /* NUL terminate the file name. */
583 sp->fts_path[p->fts_pathlen] = '\0';
586 * Return to the parent directory. If at a root node or came through
587 * a symlink, go back through the file descriptor. Otherwise, cd up
590 if (p->fts_level == FTS_ROOTLEVEL) {
591 if (FCHDIR(sp, sp->fts_rfd)) {
592 p->fts_errno = errno;
595 } else if (p->fts_flags & FTS_SYMFOLLOW) {
596 if (FCHDIR(sp, p->fts_symfd)) {
598 (void)close(p->fts_symfd);
599 __set_errno (saved_errno);
600 p->fts_errno = errno;
603 (void)close(p->fts_symfd);
604 } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
605 fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
606 p->fts_errno = errno;
609 p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
610 if (p->fts_errno == 0)
611 LEAVE_DIR (sp, p, "3");
613 return ISSET(FTS_STOP) ? NULL : p;
617 * Fts_set takes the stream as an argument although it's not used in this
618 * implementation; it would be necessary if anyone wanted to add global
619 * semantics to fts using fts_set. An error return is allowed for similar
624 fts_set(FTS *sp ATTRIBUTE_UNUSED, FTSENT *p, int instr)
626 if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
627 instr != FTS_NOINSTR && instr != FTS_SKIP) {
628 __set_errno (EINVAL);
631 p->fts_instr = instr;
636 fts_children (register FTS *sp, int instr)
641 if (instr != 0 && instr != FTS_NAMEONLY) {
642 __set_errno (EINVAL);
646 /* Set current node pointer. */
650 * Errno set to 0 so user can distinguish empty directory from
655 /* Fatal errors stop here. */
659 /* Return logical hierarchy of user's arguments. */
660 if (p->fts_info == FTS_INIT)
661 return (p->fts_link);
664 * If not a directory being visited in pre-order, stop here. Could
665 * allow FTS_DNR, assuming the user has fixed the problem, but the
666 * same effect is available with FTS_AGAIN.
668 if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
671 /* Free up any previous child list. */
672 if (sp->fts_child != NULL)
673 fts_lfree(sp->fts_child);
675 if (instr == FTS_NAMEONLY) {
682 * If using chdir on a relative file name and called BEFORE fts_read
683 * does its chdir to the root of a traversal, we can lose -- we need to
684 * chdir into the subdirectory, and we don't know where the current
685 * directory is, so we can't get back so that the upcoming chdir by
686 * fts_read will work.
688 if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
690 return (sp->fts_child = fts_build(sp, instr));
692 if ((fd = diropen (".")) < 0)
693 return (sp->fts_child = NULL);
694 sp->fts_child = fts_build(sp, instr);
700 return (sp->fts_child);
704 * This is the tricky part -- do not casually change *anything* in here. The
705 * idea is to build the linked list of entries that are used by fts_children
706 * and fts_read. There are lots of special cases.
708 * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
709 * set and it's a physical walk (so that symbolic links can't be directories),
710 * we can do things quickly. First, if it's a 4.4BSD file system, the type
711 * of the file is in the directory entry. Otherwise, we assume that the number
712 * of subdirectories in a node is equal to the number of links to the parent.
713 * The former skips all stat calls. The latter skips stat calls in any leaf
714 * directories and for any files after the subdirectories in the directory have
715 * been found, cutting the stat calls by about 2/3.
719 fts_build (register FTS *sp, int type)
721 register struct dirent *dp;
722 register FTSENT *p, *head;
723 register size_t nitems;
734 size_t len, maxlen, new_len;
737 /* Set current node pointer. */
741 * Open the directory for reading. If this fails, we're done.
742 * If being called from fts_read, set the fts_info field.
744 #if defined FTS_WHITEOUT && 0
745 if (ISSET(FTS_WHITEOUT))
746 oflag = DTF_NODUP|DTF_REWIND;
748 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
750 # define __opendir2(file, flag) opendir(file)
752 if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
754 cur->fts_info = FTS_DNR;
755 cur->fts_errno = errno;
761 * Nlinks is the number of possible entries of type directory in the
762 * directory if we're cheating on stat calls, 0 if we're not doing
763 * any stat calls at all, (nlink_t) -1 if we're statting everything.
765 if (type == BNAMES) {
767 /* Be quiet about nostat, GCC. */
769 } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
770 nlinks = (cur->fts_statp->st_nlink
771 - (ISSET(FTS_SEEDOT) ? 0 : 2));
779 * If we're going to need to stat anything or we want to descend
780 * and stay in the directory, chdir. If this fails we keep going,
781 * but set a flag so we don't chdir after the post-order visit.
782 * We won't be able to stat anything, but we can still return the
783 * names themselves. Note, that since fts_read won't be able to
784 * chdir into the directory, it will have to return different file
785 * names than before, i.e. "a/b" instead of "b". Since the node
786 * has already been visited in pre-order, have to wait until the
787 * post-order visit to return the error. There is a special case
788 * here, if there was nothing to stat then it's not an error to
789 * not be able to stat. This is all fairly nasty. If a program
790 * needed sorted entries or stat information, they had better be
791 * checking FTS_NS on the returned nodes.
794 if (nlinks || type == BREAD) {
795 if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
796 if (nlinks && type == BREAD)
797 cur->fts_errno = errno;
798 cur->fts_flags |= FTS_DONTCHDIR;
809 * Figure out the max file name length that can be stored in the
810 * current buffer -- the inner loop allocates more space as necessary.
811 * We really wouldn't have to do the maxlen calculations here, we
812 * could do them in fts_read before returning the name, but it's a
813 * lot easier here since the length is part of the dirent structure.
815 * If not changing directories set a pointer so that can just append
816 * each new component into the file name.
819 if (ISSET(FTS_NOCHDIR)) {
820 cp = sp->fts_path + len;
823 /* GCC, you're too verbose. */
827 maxlen = sp->fts_pathlen - len;
829 level = cur->fts_level + 1;
831 /* Read the directory, attaching each entry to the `link' pointer. */
833 for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
834 if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
837 if ((p = fts_alloc(sp, dp->d_name, NAMLEN (dp))) == NULL)
839 if (NAMLEN (dp) >= maxlen) {/* include space for NUL */
840 oldaddr = sp->fts_path;
841 if (! fts_palloc(sp, NAMLEN (dp) + len + 1)) {
843 * No more memory. Save
844 * errno, free up the current structure and the
845 * structures already allocated.
847 mem1: saved_errno = errno;
852 cur->fts_info = FTS_ERR;
854 __set_errno (saved_errno);
857 /* Did realloc() change the pointer? */
858 if (oldaddr != sp->fts_path) {
860 if (ISSET(FTS_NOCHDIR))
861 cp = sp->fts_path + len;
863 maxlen = sp->fts_pathlen - len;
866 new_len = len + NAMLEN (dp);
869 * In the unlikely even that we would end up
870 * with a file name longer than SIZE_MAX, free up
871 * the current structure and the structures already
872 * allocated, then error out with ENAMETOOLONG.
877 cur->fts_info = FTS_ERR;
879 __set_errno (ENAMETOOLONG);
882 p->fts_level = level;
883 p->fts_parent = sp->fts_cur;
884 p->fts_pathlen = new_len;
886 #if defined FTS_WHITEOUT && 0
887 if (dp->d_type == DT_WHT)
888 p->fts_flags |= FTS_ISW;
893 p->fts_info = FTS_NS;
894 p->fts_errno = cderrno;
896 p->fts_info = FTS_NSOK;
897 p->fts_accpath = cur->fts_accpath;
898 } else if (nlinks == 0
899 #if HAVE_STRUCT_DIRENT_D_TYPE
901 dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
905 ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
906 p->fts_info = FTS_NSOK;
908 /* Build a file name for fts_stat to stat. */
909 if (ISSET(FTS_NOCHDIR)) {
910 p->fts_accpath = p->fts_path;
911 memmove(cp, p->fts_name, p->fts_namelen + 1);
913 p->fts_accpath = p->fts_name;
915 p->fts_info = fts_stat(sp, p, false);
917 /* Decrement link count if applicable. */
918 if (nlinks > 0 && (p->fts_info == FTS_D ||
919 p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
923 /* We walk in directory order so "ls -f" doesn't get upset. */
937 * If realloc() changed the address of the file name, adjust the
938 * addresses for the rest of the tree and the dir list.
941 fts_padjust(sp, head);
944 * If not changing directories, reset the file name back to original
947 if (ISSET(FTS_NOCHDIR)) {
948 if (len == sp->fts_pathlen || nitems == 0)
954 * If descended after called from fts_children or after called from
955 * fts_read and nothing found, get back. At the root level we use
956 * the saved fd; if one of fts_open()'s arguments is a relative name
957 * to an empty directory, we wind up here with no other way back. If
958 * can't get back, we're done.
960 if (descend && (type == BCHILD || !nitems) &&
961 (cur->fts_level == FTS_ROOTLEVEL ?
962 FCHDIR(sp, sp->fts_rfd) :
963 fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
964 cur->fts_info = FTS_ERR;
969 /* If didn't find anything, return NULL. */
972 cur->fts_info = FTS_DP;
976 /* Sort the entries. */
977 if (sp->fts_compar && nitems > 1)
978 head = fts_sort(sp, head, nitems);
984 /* Walk ->fts_parent links starting at E_CURR, until the root of the
985 current hierarchy. There should be a directory with dev/inode
986 matching those of AD. If not, print a lot of diagnostics. */
988 find_matching_ancestor (FTSENT const *e_curr, struct Active_dir const *ad)
991 for (ent = e_curr; ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
993 if (ad->ino == ent->fts_statp->st_ino
994 && ad->dev == ent->fts_statp->st_dev)
997 printf ("ERROR: tree dir, %s, not active\n", ad->fts_ent->fts_accpath);
998 printf ("active dirs:\n");
1000 ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1001 printf (" %s(%"PRIuMAX"/%"PRIuMAX") to %s(%"PRIuMAX"/%"PRIuMAX")...\n",
1002 ad->fts_ent->fts_accpath,
1003 (uintmax_t) ad->dev,
1004 (uintmax_t) ad->ino,
1006 (uintmax_t) ent->fts_statp->st_dev,
1007 (uintmax_t) ent->fts_statp->st_ino);
1011 fts_cross_check (FTS const *sp)
1013 FTSENT const *ent = sp->fts_cur;
1015 if ( ! ISSET (FTS_TIGHT_CYCLE_CHECK))
1018 Dprintf (("fts-cross-check cur=%s\n", ent->fts_path));
1019 /* Make sure every parent dir is in the tree. */
1020 for (t = ent->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1022 struct Active_dir ad;
1023 ad.ino = t->fts_statp->st_ino;
1024 ad.dev = t->fts_statp->st_dev;
1025 if ( ! hash_lookup (sp->fts_cycle.ht, &ad))
1026 printf ("ERROR: active dir, %s, not in tree\n", t->fts_path);
1029 /* Make sure every dir in the tree is an active dir.
1030 But ENT is not necessarily a directory. If so, just skip this part. */
1031 if (ent->fts_parent->fts_level >= FTS_ROOTLEVEL
1032 && (ent->fts_info == FTS_DP
1033 || ent->fts_info == FTS_D))
1035 struct Active_dir *ad;
1036 for (ad = hash_get_first (sp->fts_cycle.ht); ad != NULL;
1037 ad = hash_get_next (sp->fts_cycle.ht, ad))
1039 find_matching_ancestor (ent, ad);
1045 static unsigned short int
1047 fts_stat(FTS *sp, register FTSENT *p, bool follow)
1049 struct stat *sbp = p->fts_statp;
1052 #if defined FTS_WHITEOUT && 0
1053 /* check for whiteout */
1054 if (p->fts_flags & FTS_ISW) {
1055 memset(sbp, '\0', sizeof (*sbp));
1056 sbp->st_mode = S_IFWHT;
1062 * If doing a logical walk, or application requested FTS_FOLLOW, do
1063 * a stat(2). If that fails, check for a non-existent symlink. If
1064 * fail, set the errno from the stat call.
1066 if (ISSET(FTS_LOGICAL) || follow) {
1067 if (stat(p->fts_accpath, sbp)) {
1068 saved_errno = errno;
1069 if (!lstat(p->fts_accpath, sbp)) {
1071 return (FTS_SLNONE);
1073 p->fts_errno = saved_errno;
1076 } else if (lstat(p->fts_accpath, sbp)) {
1077 p->fts_errno = errno;
1078 err: memset(sbp, 0, sizeof(struct stat));
1082 if (S_ISDIR(sbp->st_mode)) {
1083 if (ISDOT(p->fts_name))
1089 * Cycle detection is done by brute force when the directory
1090 * is first encountered. If the tree gets deep enough or the
1091 * number of symbolic links to directories is high enough,
1092 * something faster might be worthwhile.
1096 for (t = p->fts_parent;
1097 t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1098 if (sbp->st_ino == t->fts_statp->st_ino
1099 && sbp->st_dev == t->fts_statp->st_dev)
1109 if (S_ISLNK(sbp->st_mode))
1111 if (S_ISREG(sbp->st_mode))
1113 return (FTS_DEFAULT);
1117 fts_compar (void const *a, void const *b)
1119 /* Convert A and B to the correct types, to pacify the compiler, and
1120 for portability to bizarre hosts where "void const *" and "FTSENT
1121 const **" differ in runtime representation. The comparison
1122 function cannot modify *a and *b, but there is no compile-time
1124 FTSENT const **pa = (FTSENT const **) a;
1125 FTSENT const **pb = (FTSENT const **) b;
1126 return pa[0]->fts_fts->fts_compar (pa, pb);
1131 fts_sort (FTS *sp, FTSENT *head, register size_t nitems)
1133 register FTSENT **ap, *p;
1135 /* On most modern hosts, void * and FTSENT ** have the same
1136 run-time representation, and one can convert sp->fts_compar to
1137 the type qsort expects without problem. Use the heuristic that
1138 this is OK if the two pointer types are the same size, and if
1139 converting FTSENT ** to long int is the same as converting
1140 FTSENT ** to void * and then to long int. This heuristic isn't
1141 valid in general but we don't know of any counterexamples. */
1143 int (*compare) (void const *, void const *) =
1144 ((sizeof &dummy == sizeof (void *)
1145 && (long int) &dummy == (long int) (void *) &dummy)
1146 ? (int (*) (void const *, void const *)) sp->fts_compar
1150 * Construct an array of pointers to the structures and call qsort(3).
1151 * Reassemble the array in the order returned by qsort. If unable to
1152 * sort for memory reasons, return the directory entries in their
1153 * current order. Allocate enough space for the current needs plus
1154 * 40 so don't realloc one entry at a time.
1156 if (nitems > sp->fts_nitems) {
1159 sp->fts_nitems = nitems + 40;
1160 if (SIZE_MAX / sizeof *a < sp->fts_nitems
1161 || ! (a = realloc (sp->fts_array,
1162 sp->fts_nitems * sizeof *a))) {
1163 free(sp->fts_array);
1164 sp->fts_array = NULL;
1170 for (ap = sp->fts_array, p = head; p; p = p->fts_link)
1172 qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), compare);
1173 for (head = *(ap = sp->fts_array); --nitems; ++ap)
1174 ap[0]->fts_link = ap[1];
1175 ap[0]->fts_link = NULL;
1181 fts_alloc (FTS *sp, const char *name, register size_t namelen)
1187 * The file name is a variable length array. Allocate the FTSENT
1188 * structure and the file name in one chunk.
1190 len = sizeof(FTSENT) + namelen;
1191 if ((p = malloc(len)) == NULL)
1194 /* Copy the name and guarantee NUL termination. */
1195 memmove(p->fts_name, name, namelen);
1196 p->fts_name[namelen] = '\0';
1198 p->fts_namelen = namelen;
1200 p->fts_path = sp->fts_path;
1203 p->fts_instr = FTS_NOINSTR;
1205 p->fts_pointer = NULL;
1211 fts_lfree (register FTSENT *head)
1215 /* Free a linked list of structures. */
1216 while ((p = head)) {
1217 head = head->fts_link;
1223 * Allow essentially unlimited file name lengths; find, rm, ls should
1224 * all work on any tree. Most systems will allow creation of file
1225 * names much longer than MAXPATHLEN, even though the kernel won't
1226 * resolve them. Add the size (not just what's needed) plus 256 bytes
1227 * so don't realloc the file name 2 bytes at a time.
1231 fts_palloc (FTS *sp, size_t more)
1234 size_t new_len = sp->fts_pathlen + more + 256;
1237 * See if fts_pathlen would overflow.
1239 if (new_len < sp->fts_pathlen) {
1242 sp->fts_path = NULL;
1244 sp->fts_path = NULL;
1245 __set_errno (ENAMETOOLONG);
1248 sp->fts_pathlen = new_len;
1249 p = realloc(sp->fts_path, sp->fts_pathlen);
1252 sp->fts_path = NULL;
1260 * When the file name is realloc'd, have to fix all of the pointers in
1261 * structures already returned.
1265 fts_padjust (FTS *sp, FTSENT *head)
1268 char *addr = sp->fts_path;
1270 #define ADJUST(p) do { \
1271 if ((p)->fts_accpath != (p)->fts_name) { \
1272 (p)->fts_accpath = \
1273 (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
1275 (p)->fts_path = addr; \
1277 /* Adjust the current set of children. */
1278 for (p = sp->fts_child; p; p = p->fts_link)
1281 /* Adjust the rest of the tree, including the current level. */
1282 for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
1284 p = p->fts_link ? p->fts_link : p->fts_parent;
1290 fts_maxarglen (char * const *argv)
1294 for (max = 0; *argv; ++argv)
1295 if ((len = strlen(*argv)) > max)
1301 * Change to dir specified by fd or file name without getting
1302 * tricked by someone changing the world out from underneath us.
1303 * Assumes p->fts_statp->st_dev and p->fts_statp->st_ino are filled in.
1307 fts_safe_changedir (FTS *sp, FTSENT *p, int fd, char const *dir)
1309 int ret, oerrno, newfd;
1313 if (ISSET(FTS_NOCHDIR))
1315 if (fd < 0 && (newfd = diropen (dir)) < 0)
1317 if (fstat(newfd, &sb)) {
1321 if (p->fts_statp->st_dev != sb.st_dev
1322 || p->fts_statp->st_ino != sb.st_ino) {
1323 __set_errno (ENOENT); /* disinformation */
1327 ret = fchdir(newfd);
1332 __set_errno (oerrno);