2 * Copyright (c) 1990, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid
[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
36 #endif /* LIBC_SCCS and not lint */
38 #if HAVE_SYS_PARAM_H || defined _LIBC
39 # include <sys/param.h>
42 # include <include/sys/stat.h>
44 # include <sys/stat.h>
55 # include <inttypes.h>
60 # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
64 # define NAMLEN(dirent) strlen ((dirent)->d_name)
66 # define dirent direct
67 # define NAMLEN(dirent) (dirent)->d_namlen
69 # include <sys/ndir.h>
82 # define close __close
84 # define closedir __closedir
86 # define fchdir __fchdir
90 # define opendir __opendir
92 # define readdir __readdir
94 # undef internal_function
95 # define internal_function /* empty */
98 /* Arrange to make lstat calls go through the wrapper function
99 on systems with an lstat function that does not dereference symlinks
100 that are specified with a trailing slash. */
101 #if ! _LIBC && ! LSTAT_FOLLOWS_SLASHED_SYMLINK
102 int rpl_lstat (const char *, struct stat
*);
104 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
108 # define __set_errno(Val) errno = (Val)
111 /* Largest alignment size needed, minus one.
112 Usually long double is the worst case. */
114 # define ALIGNBYTES (__alignof__ (long double) - 1)
116 # define ALIGNBYTES (sizeof (long double) - 1)
118 /* Align P to that size. */
120 # define ALIGN(p) (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES)
124 static FTSENT
*fts_alloc
__P((FTS
*, const char *, int)) internal_function
;
125 static FTSENT
*fts_build
__P((FTS
*, int)) internal_function
;
126 static void fts_lfree
__P((FTSENT
*)) internal_function
;
127 static void fts_load
__P((FTS
*, FTSENT
*)) internal_function
;
128 static size_t fts_maxarglen
__P((char * const *)) internal_function
;
129 static void fts_padjust
__P((FTS
*, FTSENT
*)) internal_function
;
130 static int fts_palloc
__P((FTS
*, size_t)) internal_function
;
131 static FTSENT
*fts_sort
__P((FTS
*, FTSENT
*, int)) internal_function
;
132 static u_short fts_stat
__P((FTS
*, FTSENT
*, int)) internal_function
;
133 static int fts_safe_changedir
__P((FTS
*, FTSENT
*, int, const char *))
137 # define MAX(a,b) ((a) > (b) ? (a) : (b))
140 #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
142 #define CLR(opt) (sp->fts_options &= ~(opt))
143 #define ISSET(opt) (sp->fts_options & (opt))
144 #define SET(opt) (sp->fts_options |= (opt))
146 #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
148 /* fts_build flags */
149 #define BCHILD 1 /* fts_children */
150 #define BNAMES 2 /* fts_children, names only */
151 #define BREAD 3 /* fts_read */
153 #define HT_INITIAL_SIZE 31
158 # define Dprintf(x) do { if (fts_debug) printf x; } while (0)
163 #define ENTER_DIR(Fts, Ent, Tag) \
165 Dprintf ((" %s-entering: %s\n", Tag, (Ent)->fts_path)); \
169 #define LEAVE_DIR(Fts, Ent, Tag) \
171 Dprintf ((" %s-leaving: %s\n", Tag, (Ent)->fts_path)); \
175 /* Use these each of these to map a device/inode pair to an FTSENT. */
184 AD_compare (void const *x
, void const *y
)
186 struct Active_dir
const *ax
= x
;
187 struct Active_dir
const *ay
= y
;
188 return ax
->ino
== ay
->ino
189 && ax
->dev
== ay
->dev
;
193 AD_hash (void const *x
, size_t table_size
)
195 struct Active_dir
const *ax
= x
;
196 return (uintmax_t) ax
->ino
% table_size
;
200 enter_dir (FTS
*fts
, FTSENT
*ent
)
202 if (fts
->active_dir_ht
)
204 struct stat
const *st
= ent
->fts_statp
;
205 struct Active_dir
*ad
= malloc (sizeof (struct Active_dir
));
206 struct Active_dir
*ad_from_table
;
211 ad
->dev
= st
->st_dev
;
212 ad
->ino
= st
->st_ino
;
215 /* See if we've already encountered this directory.
216 This can happen when following symlinks as well as
217 with a corrupted directory hierarchy. */
218 ad_from_table
= hash_insert (fts
->active_dir_ht
, ad
);
220 if (ad_from_table
== NULL
)
223 /* Insertion failed due to lack of memory. Free the hash
224 table and turn off this sort of cycle detection. */
225 hash_free (fts
->active_dir_ht
);
226 fts
->active_dir_ht
= NULL
;
230 if (ad_from_table
!= ad
)
232 /* There was an entry with matching dev/inode already in the table.
233 Record the fact that we've found a cycle. */
234 ent
->fts_cycle
= ad_from_table
->fts_ent
;
235 ent
->fts_info
= FTS_DC
;
237 /* ad was not inserted, so free it. */
241 else if (fts
->cycle_state
)
243 if (cycle_check (fts
->cycle_state
, ent
->fts_statp
))
245 /* FIXME: setting fts_cycle like this isn't proper.
246 To do what the documentation requires, we'd have to
247 go around the cycle again and find the right entry.
248 But no callers in coreutils use the fts_cycle member. */
249 ent
->fts_cycle
= ent
;
250 ent
->fts_info
= FTS_DC
;
256 leave_dir (FTS
*fts
, FTSENT
*ent
)
258 if (fts
->active_dir_ht
)
260 struct stat
const *st
= ent
->fts_statp
;
261 struct Active_dir obj
;
263 obj
.dev
= st
->st_dev
;
264 obj
.ino
= st
->st_ino
;
265 found
= hash_delete (fts
->active_dir_ht
, &obj
);
273 fts_open(argv
, options
, compar
)
275 register int options
;
276 int (*compar
) __P((const FTSENT
**, const FTSENT
**));
279 register FTSENT
*p
, *root
;
281 FTSENT
*parent
, *tmp
= NULL
; /* pacify gcc */
285 if (options
& ~FTS_OPTIONMASK
) {
286 __set_errno (EINVAL
);
290 /* Allocate/initialize the stream */
291 if ((sp
= malloc((u_int
)sizeof(FTS
))) == NULL
)
293 memset(sp
, 0, sizeof(FTS
));
294 sp
->fts_compar
= (int (*) __P((const void *, const void *))) compar
;
295 sp
->fts_options
= options
;
297 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
298 if (ISSET(FTS_LOGICAL
))
302 * Start out with 1K of path space, and enough, in any case,
303 * to hold the user's paths.
306 # define MAXPATHLEN 1024
308 if (fts_palloc(sp
, MAX(fts_maxarglen(argv
), MAXPATHLEN
)))
311 /* Allocate/initialize root's parent. */
312 if ((parent
= fts_alloc(sp
, "", 0)) == NULL
)
314 parent
->fts_level
= FTS_ROOTPARENTLEVEL
;
316 /* Allocate/initialize root(s). */
317 for (root
= NULL
, nitems
= 0; *argv
!= NULL
; ++argv
, ++nitems
) {
318 /* Don't allow zero-length paths. */
319 if ((len
= strlen(*argv
)) == 0) {
320 __set_errno (ENOENT
);
324 if ((p
= fts_alloc(sp
, *argv
, len
)) == NULL
)
326 p
->fts_level
= FTS_ROOTLEVEL
;
327 p
->fts_parent
= parent
;
328 p
->fts_accpath
= p
->fts_name
;
329 p
->fts_info
= fts_stat(sp
, p
, ISSET(FTS_COMFOLLOW
));
331 /* Command-line "." and ".." are real directories. */
332 if (p
->fts_info
== FTS_DOT
)
336 * If comparison routine supplied, traverse in sorted
337 * order; otherwise traverse in the order specified.
352 if (compar
&& nitems
> 1)
353 root
= fts_sort(sp
, root
, nitems
);
356 * Allocate a dummy pointer and make fts_read think that we've just
357 * finished the node before the root(s); set p->fts_info to FTS_INIT
358 * so that everything about the "current" node is ignored.
360 if ((sp
->fts_cur
= fts_alloc(sp
, "", 0)) == NULL
)
362 sp
->fts_cur
->fts_link
= root
;
363 sp
->fts_cur
->fts_info
= FTS_INIT
;
365 if (ISSET (FTS_TIGHT_CYCLE_CHECK
))
367 sp
->active_dir_ht
= hash_initialize (HT_INITIAL_SIZE
,
370 if (sp
->active_dir_ht
== NULL
)
372 sp
->cycle_state
= malloc (sizeof *sp
->cycle_state
);
376 sp
->cycle_state
= malloc (sizeof *sp
->cycle_state
);
377 if (sp
->cycle_state
== NULL
)
379 cycle_check_init (sp
->cycle_state
);
380 sp
->active_dir_ht
= NULL
;
384 * If using chdir(2), grab a file descriptor pointing to dot to ensure
385 * that we can get back here; this could be avoided for some paths,
386 * but almost certainly not worth the effort. Slashes, symbolic links,
387 * and ".." are all fairly nasty problems. Note, if we can't get the
388 * descriptor we run anyway, just more slowly.
390 if (!ISSET(FTS_NOCHDIR
)
391 && (sp
->fts_rfd
= open(".", O_RDONLY
, 0)) < 0)
396 mem3
: fts_lfree(root
);
398 mem2
: free(sp
->fts_path
);
413 * Load the stream structure for the next traversal. Since we don't
414 * actually enter the directory until after the preorder visit, set
415 * the fts_accpath field specially so the chdir gets done to the right
416 * place and the user can access the first node. From fts_open it's
417 * known that the path will fit.
419 len
= p
->fts_pathlen
= p
->fts_namelen
;
420 memmove(sp
->fts_path
, p
->fts_name
, len
+ 1);
421 if ((cp
= strrchr(p
->fts_name
, '/')) && (cp
!= p
->fts_name
|| cp
[1])) {
423 memmove(p
->fts_name
, cp
, len
+ 1);
424 p
->fts_namelen
= len
;
426 p
->fts_accpath
= p
->fts_path
= sp
->fts_path
;
427 sp
->fts_dev
= p
->fts_dev
;
434 register FTSENT
*freep
, *p
;
438 * This still works if we haven't read anything -- the dummy structure
439 * points to the root list, so we step through to the end of the root
440 * list which has a valid parent pointer.
443 for (p
= sp
->fts_cur
; p
->fts_level
>= FTS_ROOTLEVEL
;) {
445 p
= p
->fts_link
!= NULL
? p
->fts_link
: p
->fts_parent
;
451 /* Free up child linked list, sort array, path buffer. */
453 fts_lfree(sp
->fts_child
);
458 /* Return to original directory, save errno if necessary. */
459 if (!ISSET(FTS_NOCHDIR
)) {
460 if (fchdir(sp
->fts_rfd
))
462 (void)close(sp
->fts_rfd
);
465 /* Free any memory used for cycle detection. */
466 if (sp
->active_dir_ht
)
467 hash_free (sp
->active_dir_ht
);
469 free (sp
->cycle_state
);
471 /* Free up the stream pointer. */
474 /* Set errno and return. */
476 __set_errno (saved_errno
);
484 * Special case of "/" at the end of the path so that slashes aren't
485 * appended which would cause paths to be written as "....//foo".
488 (p->fts_path[p->fts_pathlen - 1] == '/' \
489 ? p->fts_pathlen - 1 : p->fts_pathlen)
495 register FTSENT
*p
, *tmp
;
500 /* If finished or unrecoverable error, return NULL. */
501 if (sp
->fts_cur
== NULL
|| ISSET(FTS_STOP
))
504 /* Set current node pointer. */
507 /* Save and zero out user instructions. */
508 instr
= p
->fts_instr
;
509 p
->fts_instr
= FTS_NOINSTR
;
511 /* Any type of file may be re-visited; re-stat and re-turn. */
512 if (instr
== FTS_AGAIN
) {
513 p
->fts_info
= fts_stat(sp
, p
, 0);
516 Dprintf (("fts_read: p=%s\n",
517 p
->fts_info
== FTS_INIT
? "" : p
->fts_path
));
520 * Following a symlink -- SLNONE test allows application to see
521 * SLNONE and recover. If indirecting through a symlink, have
522 * keep a pointer to current location. If unable to get that
523 * pointer, follow fails.
525 if (instr
== FTS_FOLLOW
&&
526 (p
->fts_info
== FTS_SL
|| p
->fts_info
== FTS_SLNONE
)) {
527 p
->fts_info
= fts_stat(sp
, p
, 1);
528 if (p
->fts_info
== FTS_D
&& !ISSET(FTS_NOCHDIR
)) {
529 if ((p
->fts_symfd
= open(".", O_RDONLY
, 0)) < 0) {
530 p
->fts_errno
= errno
;
531 p
->fts_info
= FTS_ERR
;
533 p
->fts_flags
|= FTS_SYMFOLLOW
;
535 if (p
->fts_info
== FTS_D
)
536 ENTER_DIR (sp
, p
, "7");
540 /* Directory in pre-order. */
541 if (p
->fts_info
== FTS_D
) {
542 /* If skipped or crossed mount point, do post-order visit. */
543 if (instr
== FTS_SKIP
||
544 (ISSET(FTS_XDEV
) && p
->fts_dev
!= sp
->fts_dev
)) {
545 if (p
->fts_flags
& FTS_SYMFOLLOW
)
546 (void)close(p
->fts_symfd
);
548 fts_lfree(sp
->fts_child
);
549 sp
->fts_child
= NULL
;
551 p
->fts_info
= FTS_DP
;
552 LEAVE_DIR (sp
, p
, "1");
556 /* Rebuild if only read the names and now traversing. */
557 if (sp
->fts_child
!= NULL
&& ISSET(FTS_NAMEONLY
)) {
559 fts_lfree(sp
->fts_child
);
560 sp
->fts_child
= NULL
;
564 * Cd to the subdirectory.
566 * If have already read and now fail to chdir, whack the list
567 * to make the names come out right, and set the parent errno
568 * so the application will eventually get an error condition.
569 * Set the FTS_DONTCHDIR flag so that when we logically change
570 * directories back to the parent we don't do a chdir.
572 * If haven't read do so. If the read fails, fts_build sets
573 * FTS_STOP or the fts_info field of the node.
575 if (sp
->fts_child
!= NULL
) {
576 if (fts_safe_changedir(sp
, p
, -1, p
->fts_accpath
)) {
577 p
->fts_errno
= errno
;
578 p
->fts_flags
|= FTS_DONTCHDIR
;
579 for (p
= sp
->fts_child
; p
!= NULL
;
582 p
->fts_parent
->fts_accpath
;
584 } else if ((sp
->fts_child
= fts_build(sp
, BREAD
)) == NULL
) {
587 /* If fts_build's call to fts_safe_changedir failed
588 because it was not able to fchdir into a
589 subdirectory, tell the caller. */
591 p
->fts_info
= FTS_ERR
;
592 /* FIXME: see if this should be in an else block */
593 LEAVE_DIR (sp
, p
, "2");
597 sp
->fts_child
= NULL
;
601 /* Move to the next node on this level. */
603 if ((p
= p
->fts_link
) != NULL
) {
607 * If reached the top, return to the original directory (or
608 * the root of the tree), and load the paths for the next root.
610 if (p
->fts_level
== FTS_ROOTLEVEL
) {
611 if (FCHDIR(sp
, sp
->fts_rfd
)) {
616 if (p
->fts_info
== FTS_D
)
617 ENTER_DIR (sp
, p
, "8");
618 return (sp
->fts_cur
= p
);
622 * User may have called fts_set on the node. If skipped,
623 * ignore. If followed, get a file descriptor so we can
624 * get back if necessary.
626 if (p
->fts_instr
== FTS_SKIP
)
628 if (p
->fts_instr
== FTS_FOLLOW
) {
629 p
->fts_info
= fts_stat(sp
, p
, 1);
630 if (p
->fts_info
== FTS_D
&& !ISSET(FTS_NOCHDIR
)) {
632 open(".", O_RDONLY
, 0)) < 0) {
633 p
->fts_errno
= errno
;
634 p
->fts_info
= FTS_ERR
;
636 p
->fts_flags
|= FTS_SYMFOLLOW
;
638 p
->fts_instr
= FTS_NOINSTR
;
641 name
: t
= sp
->fts_path
+ NAPPEND(p
->fts_parent
);
643 memmove(t
, p
->fts_name
, p
->fts_namelen
+ 1);
644 if (p
->fts_info
== FTS_D
)
645 ENTER_DIR (sp
, p
, "9");
646 return (sp
->fts_cur
= p
);
649 /* Move up to the parent node. */
653 if (p
->fts_level
== FTS_ROOTPARENTLEVEL
) {
655 * Done; free everything up and set errno to 0 so the user
656 * can distinguish between error and EOF.
660 return (sp
->fts_cur
= NULL
);
663 /* NUL terminate the pathname. */
664 sp
->fts_path
[p
->fts_pathlen
] = '\0';
667 * Return to the parent directory. If at a root node or came through
668 * a symlink, go back through the file descriptor. Otherwise, cd up
671 if (p
->fts_level
== FTS_ROOTLEVEL
) {
672 if (FCHDIR(sp
, sp
->fts_rfd
)) {
676 } else if (p
->fts_flags
& FTS_SYMFOLLOW
) {
677 if (FCHDIR(sp
, p
->fts_symfd
)) {
679 (void)close(p
->fts_symfd
);
680 __set_errno (saved_errno
);
684 (void)close(p
->fts_symfd
);
685 } else if (!(p
->fts_flags
& FTS_DONTCHDIR
) &&
686 fts_safe_changedir(sp
, p
->fts_parent
, -1, "..")) {
690 p
->fts_info
= p
->fts_errno
? FTS_ERR
: FTS_DP
;
691 if (p
->fts_errno
== 0)
692 LEAVE_DIR (sp
, p
, "3");
693 return (sp
->fts_cur
= p
);
697 * Fts_set takes the stream as an argument although it's not used in this
698 * implementation; it would be necessary if anyone wanted to add global
699 * semantics to fts using fts_set. An error return is allowed for similar
704 fts_set(sp
, p
, instr
)
709 if (instr
!= 0 && instr
!= FTS_AGAIN
&& instr
!= FTS_FOLLOW
&&
710 instr
!= FTS_NOINSTR
&& instr
!= FTS_SKIP
) {
711 __set_errno (EINVAL
);
714 p
->fts_instr
= instr
;
719 fts_children(sp
, instr
)
726 if (instr
!= 0 && instr
!= FTS_NAMEONLY
) {
727 __set_errno (EINVAL
);
731 /* Set current node pointer. */
735 * Errno set to 0 so user can distinguish empty directory from
740 /* Fatal errors stop here. */
744 /* Return logical hierarchy of user's arguments. */
745 if (p
->fts_info
== FTS_INIT
)
746 return (p
->fts_link
);
749 * If not a directory being visited in pre-order, stop here. Could
750 * allow FTS_DNR, assuming the user has fixed the problem, but the
751 * same effect is available with FTS_AGAIN.
753 if (p
->fts_info
!= FTS_D
/* && p->fts_info != FTS_DNR */)
756 /* Free up any previous child list. */
757 if (sp
->fts_child
!= NULL
)
758 fts_lfree(sp
->fts_child
);
760 if (instr
== FTS_NAMEONLY
) {
767 * If using chdir on a relative path and called BEFORE fts_read does
768 * its chdir to the root of a traversal, we can lose -- we need to
769 * chdir into the subdirectory, and we don't know where the current
770 * directory is, so we can't get back so that the upcoming chdir by
771 * fts_read will work.
773 if (p
->fts_level
!= FTS_ROOTLEVEL
|| p
->fts_accpath
[0] == '/' ||
775 return (sp
->fts_child
= fts_build(sp
, instr
));
777 if ((fd
= open(".", O_RDONLY
, 0)) < 0)
778 return (sp
->fts_child
= NULL
);
779 sp
->fts_child
= fts_build(sp
, instr
);
785 return (sp
->fts_child
);
789 * This is the tricky part -- do not casually change *anything* in here. The
790 * idea is to build the linked list of entries that are used by fts_children
791 * and fts_read. There are lots of special cases.
793 * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
794 * set and it's a physical walk (so that symbolic links can't be directories),
795 * we can do things quickly. First, if it's a 4.4BSD file system, the type
796 * of the file is in the directory entry. Otherwise, we assume that the number
797 * of subdirectories in a node is equal to the number of links to the parent.
798 * The former skips all stat calls. The latter skips stat calls in any leaf
799 * directories and for any files after the subdirectories in the directory have
800 * been found, cutting the stat calls by about 2/3.
808 register struct dirent
*dp
;
809 register FTSENT
*p
, *head
;
814 int cderrno
, descend
, level
, nlinks
, saved_errno
,
816 size_t len
, maxlen
, new_len
;
819 /* Set current node pointer. */
823 * Open the directory for reading. If this fails, we're done.
824 * If being called from fts_read, set the fts_info field.
826 #if defined FTS_WHITEOUT && 0
827 if (ISSET(FTS_WHITEOUT
))
828 oflag
= DTF_NODUP
|DTF_REWIND
;
830 oflag
= DTF_HIDEW
|DTF_NODUP
|DTF_REWIND
;
832 # define __opendir2(path, flag) opendir(path)
834 if ((dirp
= __opendir2(cur
->fts_accpath
, oflag
)) == NULL
) {
836 cur
->fts_info
= FTS_DNR
;
837 cur
->fts_errno
= errno
;
843 * Nlinks is the number of possible entries of type directory in the
844 * directory if we're cheating on stat calls, 0 if we're not doing
845 * any stat calls at all, -1 if we're doing stats on everything.
847 if (type
== BNAMES
) {
849 /* Be quiet about nostat, GCC. */
851 } else if (ISSET(FTS_NOSTAT
) && ISSET(FTS_PHYSICAL
)) {
852 nlinks
= cur
->fts_nlink
- (ISSET(FTS_SEEDOT
) ? 0 : 2);
860 (void)printf("nlinks == %d (cur: %d)\n", nlinks
, cur
->fts_nlink
);
861 (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
862 ISSET(FTS_NOSTAT
), ISSET(FTS_PHYSICAL
), ISSET(FTS_SEEDOT
));
865 * If we're going to need to stat anything or we want to descend
866 * and stay in the directory, chdir. If this fails we keep going,
867 * but set a flag so we don't chdir after the post-order visit.
868 * We won't be able to stat anything, but we can still return the
869 * names themselves. Note, that since fts_read won't be able to
870 * chdir into the directory, it will have to return different path
871 * names than before, i.e. "a/b" instead of "b". Since the node
872 * has already been visited in pre-order, have to wait until the
873 * post-order visit to return the error. There is a special case
874 * here, if there was nothing to stat then it's not an error to
875 * not be able to stat. This is all fairly nasty. If a program
876 * needed sorted entries or stat information, they had better be
877 * checking FTS_NS on the returned nodes.
880 if (nlinks
|| type
== BREAD
) {
881 if (fts_safe_changedir(sp
, cur
, dirfd(dirp
), NULL
)) {
882 if (nlinks
&& type
== BREAD
)
883 cur
->fts_errno
= errno
;
884 cur
->fts_flags
|= FTS_DONTCHDIR
;
887 (void)closedir(dirp
);
895 * Figure out the max file name length that can be stored in the
896 * current path -- the inner loop allocates more path as necessary.
897 * We really wouldn't have to do the maxlen calculations here, we
898 * could do them in fts_read before returning the path, but it's a
899 * lot easier here since the length is part of the dirent structure.
901 * If not changing directories set a pointer so that can just append
902 * each new name into the path.
905 if (ISSET(FTS_NOCHDIR
)) {
906 cp
= sp
->fts_path
+ len
;
909 /* GCC, you're too verbose. */
913 maxlen
= sp
->fts_pathlen
- len
;
915 level
= cur
->fts_level
+ 1;
917 /* Read the directory, attaching each entry to the `link' pointer. */
919 for (head
= tail
= NULL
, nitems
= 0; dirp
&& (dp
= readdir(dirp
));) {
920 if (!ISSET(FTS_SEEDOT
) && ISDOT(dp
->d_name
))
923 if ((p
= fts_alloc(sp
, dp
->d_name
, (int)NAMLEN (dp
))) == NULL
)
925 if (NAMLEN (dp
) >= maxlen
) {/* include space for NUL */
926 oldaddr
= sp
->fts_path
;
927 if (fts_palloc(sp
, NAMLEN (dp
) + len
+ 1)) {
929 * No more memory for path or structures. Save
930 * errno, free up the current structure and the
931 * structures already allocated.
933 mem1
: saved_errno
= errno
;
937 (void)closedir(dirp
);
938 cur
->fts_info
= FTS_ERR
;
940 __set_errno (saved_errno
);
943 /* Did realloc() change the pointer? */
944 if (oldaddr
!= sp
->fts_path
) {
946 if (ISSET(FTS_NOCHDIR
))
947 cp
= sp
->fts_path
+ len
;
949 maxlen
= sp
->fts_pathlen
- len
;
952 new_len
= len
+ NAMLEN (dp
);
955 * In the unlikely even that we would end up
956 * with a path longer than SIZE_MAX, free up
957 * the current structure and the structures already
958 * allocated, then error out with ENAMETOOLONG.
962 (void)closedir(dirp
);
963 cur
->fts_info
= FTS_ERR
;
965 __set_errno (ENAMETOOLONG
);
968 p
->fts_level
= level
;
969 p
->fts_parent
= sp
->fts_cur
;
970 p
->fts_pathlen
= new_len
;
972 #if defined FTS_WHITEOUT && 0
973 if (dp
->d_type
== DT_WHT
)
974 p
->fts_flags
|= FTS_ISW
;
979 p
->fts_info
= FTS_NS
;
980 p
->fts_errno
= cderrno
;
982 p
->fts_info
= FTS_NSOK
;
983 p
->fts_accpath
= cur
->fts_accpath
;
984 } else if (nlinks
== 0
985 # if HAVE_STRUCT_DIRENT_D_TYPE
987 dp
->d_type
!= DT_DIR
&& dp
->d_type
!= DT_UNKNOWN
)
991 ISSET(FTS_NOCHDIR
) ? p
->fts_path
: p
->fts_name
;
992 p
->fts_info
= FTS_NSOK
;
994 /* Build a file name for fts_stat to stat. */
995 if (ISSET(FTS_NOCHDIR
)) {
996 p
->fts_accpath
= p
->fts_path
;
997 memmove(cp
, p
->fts_name
, p
->fts_namelen
+ 1);
999 p
->fts_accpath
= p
->fts_name
;
1001 p
->fts_info
= fts_stat(sp
, p
, 0);
1003 /* Decrement link count if applicable. */
1004 if (nlinks
> 0 && (p
->fts_info
== FTS_D
||
1005 p
->fts_info
== FTS_DC
|| p
->fts_info
== FTS_DOT
))
1009 /* We walk in directory order so "ls -f" doesn't get upset. */
1020 (void)closedir(dirp
);
1023 * If realloc() changed the address of the path, adjust the
1024 * addresses for the rest of the tree and the dir list.
1027 fts_padjust(sp
, head
);
1030 * If not changing directories, reset the path back to original
1033 if (ISSET(FTS_NOCHDIR
)) {
1034 if (len
== sp
->fts_pathlen
|| nitems
== 0)
1040 * If descended after called from fts_children or after called from
1041 * fts_read and nothing found, get back. At the root level we use
1042 * the saved fd; if one of fts_open()'s arguments is a relative path
1043 * to an empty directory, we wind up here with no other way back. If
1044 * can't get back, we're done.
1046 if (descend
&& (type
== BCHILD
|| !nitems
) &&
1047 (cur
->fts_level
== FTS_ROOTLEVEL
?
1048 FCHDIR(sp
, sp
->fts_rfd
) :
1049 fts_safe_changedir(sp
, cur
->fts_parent
, -1, ".."))) {
1050 cur
->fts_info
= FTS_ERR
;
1055 /* If didn't find anything, return NULL. */
1058 cur
->fts_info
= FTS_DP
;
1062 /* Sort the entries. */
1063 if (sp
->fts_compar
&& nitems
> 1)
1064 head
= fts_sort(sp
, head
, nitems
);
1070 /* Walk ->fts_parent links starting at E_CURR, until the root of the
1071 current hierarchy. There should be a directory with dev/inode
1072 matching those of AD. If not, print a lot of diagnostics. */
1074 find_matching_ancestor (FTSENT
const *e_curr
, struct Active_dir
const *ad
)
1077 for (ent
= e_curr
; ent
->fts_level
>= FTS_ROOTLEVEL
; ent
= ent
->fts_parent
)
1079 if (ad
->ino
== ent
->fts_statp
->st_ino
1080 && ad
->dev
== ent
->fts_statp
->st_dev
)
1083 printf ("ERROR: tree dir, %s, not active\n", ad
->fts_ent
->fts_accpath
);
1084 printf ("active dirs:\n");
1086 ent
->fts_level
>= FTS_ROOTLEVEL
; ent
= ent
->fts_parent
)
1087 printf (" %s(%d/%d) to %s(%d/%d)...\n",
1088 ad
->fts_ent
->fts_accpath
,
1092 (int)ent
->fts_statp
->st_dev
,
1093 (int)ent
->fts_statp
->st_ino
);
1097 fts_cross_check (FTS
const *sp
)
1099 FTSENT
const *ent
= sp
->fts_cur
;
1101 if ( ! ISSET (FTS_TIGHT_CYCLE_CHECK
))
1104 Dprintf (("fts-cross-check cur=%s\n", ent
->fts_path
));
1105 /* Make sure every parent dir is in the tree. */
1106 for (t
= ent
->fts_parent
; t
->fts_level
>= FTS_ROOTLEVEL
; t
= t
->fts_parent
)
1108 struct Active_dir ad
;
1109 ad
.ino
= t
->fts_statp
->st_ino
;
1110 ad
.dev
= t
->fts_statp
->st_dev
;
1111 if ( ! hash_lookup (sp
->active_dir_ht
, &ad
))
1112 printf ("ERROR: active dir, %s, not in tree\n", t
->fts_path
);
1115 /* Make sure every dir in the tree is an active dir.
1116 But ENT is not necessarily a directory. If so, just skip this part. */
1117 if (ent
->fts_parent
->fts_level
>= FTS_ROOTLEVEL
1118 && (ent
->fts_info
== FTS_DP
1119 || ent
->fts_info
== FTS_D
))
1121 struct Active_dir
*ad
;
1122 for (ad
= hash_get_first (sp
->active_dir_ht
); ad
!= NULL
;
1123 ad
= hash_get_next (sp
->active_dir_ht
, ad
))
1125 find_matching_ancestor (ent
, ad
);
1133 fts_stat(sp
, p
, follow
)
1138 struct stat
*sbp
, sb
;
1141 /* If user needs stat info, stat buffer already allocated. */
1142 sbp
= ISSET(FTS_NOSTAT
) ? &sb
: p
->fts_statp
;
1144 #if defined FTS_WHITEOUT && 0
1145 /* check for whiteout */
1146 if (p
->fts_flags
& FTS_ISW
) {
1148 memset(sbp
, '\0', sizeof (*sbp
));
1149 sbp
->st_mode
= S_IFWHT
;
1156 * If doing a logical walk, or application requested FTS_FOLLOW, do
1157 * a stat(2). If that fails, check for a non-existent symlink. If
1158 * fail, set the errno from the stat call.
1160 if (ISSET(FTS_LOGICAL
) || follow
) {
1161 if (stat(p
->fts_accpath
, sbp
)) {
1162 saved_errno
= errno
;
1163 if (!lstat(p
->fts_accpath
, sbp
)) {
1165 return (FTS_SLNONE
);
1167 p
->fts_errno
= saved_errno
;
1170 } else if (lstat(p
->fts_accpath
, sbp
)) {
1171 p
->fts_errno
= errno
;
1172 err
: memset(sbp
, 0, sizeof(struct stat
));
1176 if (S_ISDIR(sbp
->st_mode
)) {
1178 * Set the device/inode. Used to find cycles and check for
1179 * crossing mount points. Also remember the link count, used
1180 * in fts_build to limit the number of stat calls. It is
1181 * understood that these fields are only referenced if fts_info
1184 p
->fts_dev
= sbp
->st_dev
;
1185 p
->fts_ino
= sbp
->st_ino
;
1186 p
->fts_nlink
= sbp
->st_nlink
;
1188 if (ISDOT(p
->fts_name
))
1193 if (S_ISLNK(sbp
->st_mode
))
1195 if (S_ISREG(sbp
->st_mode
))
1197 return (FTS_DEFAULT
);
1202 fts_sort(sp
, head
, nitems
)
1205 register int nitems
;
1207 register FTSENT
**ap
, *p
;
1210 * Construct an array of pointers to the structures and call qsort(3).
1211 * Reassemble the array in the order returned by qsort. If unable to
1212 * sort for memory reasons, return the directory entries in their
1213 * current order. Allocate enough space for the current needs plus
1214 * 40 so don't realloc one entry at a time.
1216 if (nitems
> sp
->fts_nitems
) {
1219 sp
->fts_nitems
= nitems
+ 40;
1220 if ((a
= realloc(sp
->fts_array
,
1221 (size_t)(sp
->fts_nitems
* sizeof(FTSENT
*)))) == NULL
) {
1222 free(sp
->fts_array
);
1223 sp
->fts_array
= NULL
;
1229 for (ap
= sp
->fts_array
, p
= head
; p
; p
= p
->fts_link
)
1231 qsort((void *)sp
->fts_array
, nitems
, sizeof(FTSENT
*), sp
->fts_compar
);
1232 for (head
= *(ap
= sp
->fts_array
); --nitems
; ++ap
)
1233 ap
[0]->fts_link
= ap
[1];
1234 ap
[0]->fts_link
= NULL
;
1240 fts_alloc(sp
, name
, namelen
)
1243 register int namelen
;
1249 * The file name is a variable length array and no stat structure is
1250 * necessary if the user has set the nostat bit. Allocate the FTSENT
1251 * structure, the file name and the stat structure in one chunk, but
1252 * be careful that the stat structure is reasonably aligned. Since the
1253 * fts_name field is declared to be of size 1, the fts_name pointer is
1254 * namelen + 2 before the first possible address of the stat structure.
1256 len
= sizeof(FTSENT
) + namelen
;
1257 if (!ISSET(FTS_NOSTAT
))
1258 len
+= sizeof(struct stat
) + ALIGNBYTES
;
1259 if ((p
= malloc(len
)) == NULL
)
1262 /* Copy the name and guarantee NUL termination. */
1263 memmove(p
->fts_name
, name
, namelen
);
1264 p
->fts_name
[namelen
] = '\0';
1266 if (!ISSET(FTS_NOSTAT
))
1267 p
->fts_statp
= (struct stat
*)ALIGN(p
->fts_name
+ namelen
+ 2);
1268 p
->fts_namelen
= namelen
;
1269 p
->fts_path
= sp
->fts_path
;
1272 p
->fts_instr
= FTS_NOINSTR
;
1274 p
->fts_pointer
= NULL
;
1281 register FTSENT
*head
;
1285 /* Free a linked list of structures. */
1286 while ((p
= head
)) {
1287 head
= head
->fts_link
;
1293 * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
1294 * Most systems will allow creation of paths much longer than MAXPATHLEN, even
1295 * though the kernel won't resolve them. Add the size (not just what's needed)
1296 * plus 256 bytes so don't realloc the path 2 bytes at a time.
1300 fts_palloc(sp
, more
)
1305 size_t new_len
= sp
->fts_pathlen
+ more
+ 256;
1308 * See if fts_pathlen would overflow.
1310 if (new_len
< sp
->fts_pathlen
) {
1313 sp
->fts_path
= NULL
;
1315 sp
->fts_path
= NULL
;
1316 __set_errno (ENAMETOOLONG
);
1319 sp
->fts_pathlen
= new_len
;
1320 p
= realloc(sp
->fts_path
, sp
->fts_pathlen
);
1323 sp
->fts_path
= NULL
;
1331 * When the path is realloc'd, have to fix all of the pointers in structures
1336 fts_padjust(sp
, head
)
1341 char *addr
= sp
->fts_path
;
1343 #define ADJUST(p) do { \
1344 if ((p)->fts_accpath != (p)->fts_name) { \
1345 (p)->fts_accpath = \
1346 (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
1348 (p)->fts_path = addr; \
1350 /* Adjust the current set of children. */
1351 for (p
= sp
->fts_child
; p
; p
= p
->fts_link
)
1354 /* Adjust the rest of the tree, including the current level. */
1355 for (p
= head
; p
->fts_level
>= FTS_ROOTLEVEL
;) {
1357 p
= p
->fts_link
? p
->fts_link
: p
->fts_parent
;
1368 for (max
= 0; *argv
; ++argv
)
1369 if ((len
= strlen(*argv
)) > max
)
1375 * Change to dir specified by fd or p->fts_accpath without getting
1376 * tricked by someone changing the world out from underneath us.
1377 * Assumes p->fts_dev and p->fts_ino are filled in.
1381 fts_safe_changedir(sp
, p
, fd
, path
)
1387 int ret
, oerrno
, newfd
;
1391 if (ISSET(FTS_NOCHDIR
))
1393 if (fd
< 0 && (newfd
= open(path
, O_RDONLY
, 0)) < 0)
1395 if (fstat(newfd
, &sb
)) {
1399 if (p
->fts_dev
!= sb
.st_dev
|| p
->fts_ino
!= sb
.st_ino
) {
1400 __set_errno (ENOENT
); /* disinformation */
1404 ret
= fchdir(newfd
);
1409 __set_errno (oerrno
);