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>
56 # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
60 # define NAMLEN(dirent) strlen ((dirent)->d_name)
62 # define dirent direct
63 # define NAMLEN(dirent) (dirent)->d_namlen
65 # include <sys/ndir.h>
78 # define close __close
80 # define closedir __closedir
82 # define fchdir __fchdir
86 # define opendir __opendir
88 # define readdir __readdir
90 # define tdestroy __tdestroy
92 # define tfind __tfind
94 # define tsearch __tsearch
96 # undef internal_function
97 # define internal_function /* empty */
100 /* Arrange to make lstat calls go through the wrapper function
101 on systems with an lstat function that does not dereference symlinks
102 that are specified with a trailing slash. */
103 #if ! _LIBC && ! LSTAT_FOLLOWS_SLASHED_SYMLINK
104 int rpl_lstat (const char *, struct stat
*);
106 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
110 # define __set_errno(Val) errno = (Val)
113 /* Largest alignment size needed, minus one.
114 Usually long double is the worst case. */
116 # define ALIGNBYTES (__alignof__ (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) ({ __typeof__ (a) _a = (a); \
138 __typeof__ (b) _b = (b); \
139 _a > _b ? _a : _b; })
142 #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
144 #define CLR(opt) (sp->fts_options &= ~(opt))
145 #define ISSET(opt) (sp->fts_options & (opt))
146 #define SET(opt) (sp->fts_options |= (opt))
148 #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
150 /* fts_build flags */
151 #define BCHILD 1 /* fts_children */
152 #define BNAMES 2 /* fts_children, names only */
153 #define BREAD 3 /* fts_read */
163 object_compare (const void *p1
, const void *p2
)
165 /* We don't need a sophisticated and useful comparison. We are only
166 interested in equality. However, we must be careful not to
167 accidentally compare `holes' in the structure. */
168 const struct known_object
*kp1
= p1
, *kp2
= p2
;
170 cmp1
= (kp1
->ino
> kp2
->ino
) - (kp1
->ino
< kp2
->ino
);
173 return (kp1
->dev
> kp2
->dev
) - (kp1
->dev
< kp2
->dev
);
177 add_object (FTS
*fts
, FTSENT
*data
, const struct stat
*st
)
179 struct known_object
*newp
= malloc (sizeof (struct known_object
));
182 newp
->dev
= st
->st_dev
;
183 newp
->ino
= st
->st_ino
;
184 newp
->fts_ent
= data
;
185 return tsearch (newp
, &fts
->fts_dir_signatures
, object_compare
) ? 0 : -1;
188 static inline FTSENT
*
189 find_object (const FTS
*fts
, const struct stat
*st
)
191 struct known_object obj
;
192 struct known_object
const *t
;
193 obj
.dev
= st
->st_dev
;
194 obj
.ino
= st
->st_ino
;
195 t
= tfind (&obj
, &fts
->fts_dir_signatures
, object_compare
);
196 return t
? t
->fts_ent
: NULL
;
200 fts_open(argv
, options
, compar
)
202 register int options
;
203 int (*compar
) __P((const FTSENT
**, const FTSENT
**));
206 register FTSENT
*p
, *root
;
208 FTSENT
*parent
, *tmp
= NULL
; /* pacify gcc */
212 if (options
& ~FTS_OPTIONMASK
) {
213 __set_errno (EINVAL
);
217 /* Allocate/initialize the stream */
218 if ((sp
= malloc((u_int
)sizeof(FTS
))) == NULL
)
220 memset(sp
, 0, sizeof(FTS
));
221 sp
->fts_compar
= (int (*) __P((const void *, const void *))) compar
;
222 sp
->fts_options
= options
;
224 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
225 if (ISSET(FTS_LOGICAL
))
229 * Start out with 1K of path space, and enough, in any case,
230 * to hold the user's paths.
233 # define MAXPATHLEN 1024
235 if (fts_palloc(sp
, MAX(fts_maxarglen(argv
), MAXPATHLEN
)))
238 /* Allocate/initialize root's parent. */
239 if ((parent
= fts_alloc(sp
, "", 0)) == NULL
)
241 parent
->fts_level
= FTS_ROOTPARENTLEVEL
;
243 /* Allocate/initialize root(s). */
244 for (root
= NULL
, nitems
= 0; *argv
!= NULL
; ++argv
, ++nitems
) {
245 /* Don't allow zero-length paths. */
246 if ((len
= strlen(*argv
)) == 0) {
247 __set_errno (ENOENT
);
251 if ((p
= fts_alloc(sp
, *argv
, len
)) == NULL
)
253 p
->fts_level
= FTS_ROOTLEVEL
;
254 p
->fts_parent
= parent
;
255 p
->fts_accpath
= p
->fts_name
;
256 p
->fts_info
= fts_stat(sp
, p
, ISSET(FTS_COMFOLLOW
));
258 /* Command-line "." and ".." are real directories. */
259 if (p
->fts_info
== FTS_DOT
)
263 * If comparison routine supplied, traverse in sorted
264 * order; otherwise traverse in the order specified.
279 if (compar
&& nitems
> 1)
280 root
= fts_sort(sp
, root
, nitems
);
283 * Allocate a dummy pointer and make fts_read think that we've just
284 * finished the node before the root(s); set p->fts_info to FTS_INIT
285 * so that everything about the "current" node is ignored.
287 if ((sp
->fts_cur
= fts_alloc(sp
, "", 0)) == NULL
)
289 sp
->fts_cur
->fts_link
= root
;
290 sp
->fts_cur
->fts_info
= FTS_INIT
;
292 sp
->fts_dir_signatures
= NULL
;
295 * If using chdir(2), grab a file descriptor pointing to dot to ensure
296 * that we can get back here; this could be avoided for some paths,
297 * but almost certainly not worth the effort. Slashes, symbolic links,
298 * and ".." are all fairly nasty problems. Note, if we can't get the
299 * descriptor we run anyway, just more slowly.
301 if (!ISSET(FTS_NOCHDIR
)
302 && (sp
->fts_rfd
= open(".", O_RDONLY
, 0)) < 0)
307 mem3
: fts_lfree(root
);
309 mem2
: free(sp
->fts_path
);
324 * Load the stream structure for the next traversal. Since we don't
325 * actually enter the directory until after the preorder visit, set
326 * the fts_accpath field specially so the chdir gets done to the right
327 * place and the user can access the first node. From fts_open it's
328 * known that the path will fit.
330 len
= p
->fts_pathlen
= p
->fts_namelen
;
331 memmove(sp
->fts_path
, p
->fts_name
, len
+ 1);
332 if ((cp
= strrchr(p
->fts_name
, '/')) && (cp
!= p
->fts_name
|| cp
[1])) {
334 memmove(p
->fts_name
, cp
, len
+ 1);
335 p
->fts_namelen
= len
;
337 p
->fts_accpath
= p
->fts_path
= sp
->fts_path
;
338 sp
->fts_dev
= p
->fts_dev
;
345 register FTSENT
*freep
, *p
;
349 * This still works if we haven't read anything -- the dummy structure
350 * points to the root list, so we step through to the end of the root
351 * list which has a valid parent pointer.
354 for (p
= sp
->fts_cur
; p
->fts_level
>= FTS_ROOTLEVEL
;) {
356 p
= p
->fts_link
!= NULL
? p
->fts_link
: p
->fts_parent
;
362 /* Free up child linked list, sort array, path buffer. */
364 fts_lfree(sp
->fts_child
);
369 /* Return to original directory, save errno if necessary. */
370 if (!ISSET(FTS_NOCHDIR
)) {
371 if (fchdir(sp
->fts_rfd
))
373 (void)close(sp
->fts_rfd
);
376 /* Free all of the directory fingerprint info. */
377 tdestroy (sp
->fts_dir_signatures
, free
);
379 /* Free up the stream pointer. */
382 /* Set errno and return. */
384 __set_errno (saved_errno
);
392 * Special case of "/" at the end of the path so that slashes aren't
393 * appended which would cause paths to be written as "....//foo".
396 (p->fts_path[p->fts_pathlen - 1] == '/' \
397 ? p->fts_pathlen - 1 : p->fts_pathlen)
403 register FTSENT
*p
, *tmp
;
408 /* If finished or unrecoverable error, return NULL. */
409 if (sp
->fts_cur
== NULL
|| ISSET(FTS_STOP
))
412 /* Set current node pointer. */
415 /* Save and zero out user instructions. */
416 instr
= p
->fts_instr
;
417 p
->fts_instr
= FTS_NOINSTR
;
419 /* Any type of file may be re-visited; re-stat and re-turn. */
420 if (instr
== FTS_AGAIN
) {
421 p
->fts_info
= fts_stat(sp
, p
, 0);
426 * Following a symlink -- SLNONE test allows application to see
427 * SLNONE and recover. If indirecting through a symlink, have
428 * keep a pointer to current location. If unable to get that
429 * pointer, follow fails.
431 if (instr
== FTS_FOLLOW
&&
432 (p
->fts_info
== FTS_SL
|| p
->fts_info
== FTS_SLNONE
)) {
433 p
->fts_info
= fts_stat(sp
, p
, 1);
434 if (p
->fts_info
== FTS_D
&& !ISSET(FTS_NOCHDIR
)) {
435 if ((p
->fts_symfd
= open(".", O_RDONLY
, 0)) < 0) {
436 p
->fts_errno
= errno
;
437 p
->fts_info
= FTS_ERR
;
439 p
->fts_flags
|= FTS_SYMFOLLOW
;
444 /* Directory in pre-order. */
445 if (p
->fts_info
== FTS_D
) {
446 /* If skipped or crossed mount point, do post-order visit. */
447 if (instr
== FTS_SKIP
||
448 (ISSET(FTS_XDEV
) && p
->fts_dev
!= sp
->fts_dev
)) {
449 if (p
->fts_flags
& FTS_SYMFOLLOW
)
450 (void)close(p
->fts_symfd
);
452 fts_lfree(sp
->fts_child
);
453 sp
->fts_child
= NULL
;
455 p
->fts_info
= FTS_DP
;
459 /* Rebuild if only read the names and now traversing. */
460 if (sp
->fts_child
!= NULL
&& ISSET(FTS_NAMEONLY
)) {
462 fts_lfree(sp
->fts_child
);
463 sp
->fts_child
= NULL
;
467 * Cd to the subdirectory.
469 * If have already read and now fail to chdir, whack the list
470 * to make the names come out right, and set the parent errno
471 * so the application will eventually get an error condition.
472 * Set the FTS_DONTCHDIR flag so that when we logically change
473 * directories back to the parent we don't do a chdir.
475 * If haven't read do so. If the read fails, fts_build sets
476 * FTS_STOP or the fts_info field of the node.
478 if (sp
->fts_child
!= NULL
) {
479 if (fts_safe_changedir(sp
, p
, -1, p
->fts_accpath
)) {
480 p
->fts_errno
= errno
;
481 p
->fts_flags
|= FTS_DONTCHDIR
;
482 for (p
= sp
->fts_child
; p
!= NULL
;
485 p
->fts_parent
->fts_accpath
;
487 } else if ((sp
->fts_child
= fts_build(sp
, BREAD
)) == NULL
) {
490 /* If fts_build's call to fts_safe_changedir failed
491 because it was not able to fchdir into a
492 subdirectory, tell the caller. */
494 p
->fts_info
= FTS_ERR
;
498 sp
->fts_child
= NULL
;
502 /* Move to the next node on this level. */
504 if ((p
= p
->fts_link
) != NULL
) {
508 * If reached the top, return to the original directory (or
509 * the root of the tree), and load the paths for the next root.
511 if (p
->fts_level
== FTS_ROOTLEVEL
) {
512 if (FCHDIR(sp
, sp
->fts_rfd
)) {
517 return (sp
->fts_cur
= p
);
521 * User may have called fts_set on the node. If skipped,
522 * ignore. If followed, get a file descriptor so we can
523 * get back if necessary.
525 if (p
->fts_instr
== FTS_SKIP
)
527 if (p
->fts_instr
== FTS_FOLLOW
) {
528 p
->fts_info
= fts_stat(sp
, p
, 1);
529 if (p
->fts_info
== FTS_D
&& !ISSET(FTS_NOCHDIR
)) {
531 open(".", O_RDONLY
, 0)) < 0) {
532 p
->fts_errno
= errno
;
533 p
->fts_info
= FTS_ERR
;
535 p
->fts_flags
|= FTS_SYMFOLLOW
;
537 p
->fts_instr
= FTS_NOINSTR
;
540 name
: t
= sp
->fts_path
+ NAPPEND(p
->fts_parent
);
542 memmove(t
, p
->fts_name
, p
->fts_namelen
+ 1);
543 return (sp
->fts_cur
= p
);
546 /* Move up to the parent node. */
550 if (p
->fts_level
== FTS_ROOTPARENTLEVEL
) {
552 * Done; free everything up and set errno to 0 so the user
553 * can distinguish between error and EOF.
557 return (sp
->fts_cur
= NULL
);
560 /* NUL terminate the pathname. */
561 sp
->fts_path
[p
->fts_pathlen
] = '\0';
564 * Return to the parent directory. If at a root node or came through
565 * a symlink, go back through the file descriptor. Otherwise, cd up
568 if (p
->fts_level
== FTS_ROOTLEVEL
) {
569 if (FCHDIR(sp
, sp
->fts_rfd
)) {
573 } else if (p
->fts_flags
& FTS_SYMFOLLOW
) {
574 if (FCHDIR(sp
, p
->fts_symfd
)) {
576 (void)close(p
->fts_symfd
);
577 __set_errno (saved_errno
);
581 (void)close(p
->fts_symfd
);
582 } else if (!(p
->fts_flags
& FTS_DONTCHDIR
) &&
583 fts_safe_changedir(sp
, p
->fts_parent
, -1, "..")) {
587 p
->fts_info
= p
->fts_errno
? FTS_ERR
: FTS_DP
;
588 return (sp
->fts_cur
= p
);
592 * Fts_set takes the stream as an argument although it's not used in this
593 * implementation; it would be necessary if anyone wanted to add global
594 * semantics to fts using fts_set. An error return is allowed for similar
599 fts_set(sp
, p
, instr
)
604 if (instr
!= 0 && instr
!= FTS_AGAIN
&& instr
!= FTS_FOLLOW
&&
605 instr
!= FTS_NOINSTR
&& instr
!= FTS_SKIP
) {
606 __set_errno (EINVAL
);
609 p
->fts_instr
= instr
;
614 fts_children(sp
, instr
)
621 if (instr
!= 0 && instr
!= FTS_NAMEONLY
) {
622 __set_errno (EINVAL
);
626 /* Set current node pointer. */
630 * Errno set to 0 so user can distinguish empty directory from
635 /* Fatal errors stop here. */
639 /* Return logical hierarchy of user's arguments. */
640 if (p
->fts_info
== FTS_INIT
)
641 return (p
->fts_link
);
644 * If not a directory being visited in pre-order, stop here. Could
645 * allow FTS_DNR, assuming the user has fixed the problem, but the
646 * same effect is available with FTS_AGAIN.
648 if (p
->fts_info
!= FTS_D
/* && p->fts_info != FTS_DNR */)
651 /* Free up any previous child list. */
652 if (sp
->fts_child
!= NULL
)
653 fts_lfree(sp
->fts_child
);
655 if (instr
== FTS_NAMEONLY
) {
662 * If using chdir on a relative path and called BEFORE fts_read does
663 * its chdir to the root of a traversal, we can lose -- we need to
664 * chdir into the subdirectory, and we don't know where the current
665 * directory is, so we can't get back so that the upcoming chdir by
666 * fts_read will work.
668 if (p
->fts_level
!= FTS_ROOTLEVEL
|| p
->fts_accpath
[0] == '/' ||
670 return (sp
->fts_child
= fts_build(sp
, instr
));
672 if ((fd
= open(".", O_RDONLY
, 0)) < 0)
673 return (sp
->fts_child
= NULL
);
674 sp
->fts_child
= fts_build(sp
, instr
);
680 return (sp
->fts_child
);
684 * This is the tricky part -- do not casually change *anything* in here. The
685 * idea is to build the linked list of entries that are used by fts_children
686 * and fts_read. There are lots of special cases.
688 * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
689 * set and it's a physical walk (so that symbolic links can't be directories),
690 * we can do things quickly. First, if it's a 4.4BSD file system, the type
691 * of the file is in the directory entry. Otherwise, we assume that the number
692 * of subdirectories in a node is equal to the number of links to the parent.
693 * The former skips all stat calls. The latter skips stat calls in any leaf
694 * directories and for any files after the subdirectories in the directory have
695 * been found, cutting the stat calls by about 2/3.
703 register struct dirent
*dp
;
704 register FTSENT
*p
, *head
;
709 int cderrno
, descend
, len
, level
, maxlen
, nlinks
, saved_errno
,
713 /* Set current node pointer. */
717 * Open the directory for reading. If this fails, we're done.
718 * If being called from fts_read, set the fts_info field.
720 #if defined FTS_WHITEOUT && 0
721 if (ISSET(FTS_WHITEOUT
))
722 oflag
= DTF_NODUP
|DTF_REWIND
;
724 oflag
= DTF_HIDEW
|DTF_NODUP
|DTF_REWIND
;
726 # define __opendir2(path, flag) opendir(path)
728 if ((dirp
= __opendir2(cur
->fts_accpath
, oflag
)) == NULL
) {
730 cur
->fts_info
= FTS_DNR
;
731 cur
->fts_errno
= errno
;
737 * Nlinks is the number of possible entries of type directory in the
738 * directory if we're cheating on stat calls, 0 if we're not doing
739 * any stat calls at all, -1 if we're doing stats on everything.
741 if (type
== BNAMES
) {
743 /* Be quiet about nostat, GCC. */
745 } else if (ISSET(FTS_NOSTAT
) && ISSET(FTS_PHYSICAL
)) {
746 nlinks
= cur
->fts_nlink
- (ISSET(FTS_SEEDOT
) ? 0 : 2);
754 (void)printf("nlinks == %d (cur: %d)\n", nlinks
, cur
->fts_nlink
);
755 (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
756 ISSET(FTS_NOSTAT
), ISSET(FTS_PHYSICAL
), ISSET(FTS_SEEDOT
));
759 * If we're going to need to stat anything or we want to descend
760 * and stay in the directory, chdir. If this fails we keep going,
761 * but set a flag so we don't chdir after the post-order visit.
762 * We won't be able to stat anything, but we can still return the
763 * names themselves. Note, that since fts_read won't be able to
764 * chdir into the directory, it will have to return different path
765 * names than before, i.e. "a/b" instead of "b". Since the node
766 * has already been visited in pre-order, have to wait until the
767 * post-order visit to return the error. There is a special case
768 * here, if there was nothing to stat then it's not an error to
769 * not be able to stat. This is all fairly nasty. If a program
770 * needed sorted entries or stat information, they had better be
771 * checking FTS_NS on the returned nodes.
774 if (nlinks
|| type
== BREAD
) {
775 if (fts_safe_changedir(sp
, cur
, dirfd(dirp
), NULL
)) {
776 if (nlinks
&& type
== BREAD
)
777 cur
->fts_errno
= errno
;
778 cur
->fts_flags
|= FTS_DONTCHDIR
;
781 (void)closedir(dirp
);
789 * Figure out the max file name length that can be stored in the
790 * current path -- the inner loop allocates more path as necessary.
791 * We really wouldn't have to do the maxlen calculations here, we
792 * could do them in fts_read before returning the path, but it's a
793 * lot easier here since the length is part of the dirent structure.
795 * If not changing directories set a pointer so that can just append
796 * each new name into the path.
799 if (ISSET(FTS_NOCHDIR
)) {
800 cp
= sp
->fts_path
+ len
;
803 /* GCC, you're too verbose. */
807 maxlen
= sp
->fts_pathlen
- len
;
809 level
= cur
->fts_level
+ 1;
811 /* Read the directory, attaching each entry to the `link' pointer. */
813 for (head
= tail
= NULL
, nitems
= 0; dirp
&& (dp
= readdir(dirp
));) {
814 if (!ISSET(FTS_SEEDOT
) && ISDOT(dp
->d_name
))
817 if ((p
= fts_alloc(sp
, dp
->d_name
, (int)NAMLEN (dp
))) == NULL
)
819 if (NAMLEN (dp
) >= maxlen
) {/* include space for NUL */
820 oldaddr
= sp
->fts_path
;
821 if (fts_palloc(sp
, NAMLEN (dp
) + len
+ 1)) {
823 * No more memory for path or structures. Save
824 * errno, free up the current structure and the
825 * structures already allocated.
827 mem1
: saved_errno
= errno
;
831 (void)closedir(dirp
);
832 cur
->fts_info
= FTS_ERR
;
834 __set_errno (saved_errno
);
837 /* Did realloc() change the pointer? */
838 if (oldaddr
!= sp
->fts_path
) {
840 if (ISSET(FTS_NOCHDIR
))
841 cp
= sp
->fts_path
+ len
;
843 maxlen
= sp
->fts_pathlen
- len
;
846 if (len
+ NAMLEN (dp
) >= USHRT_MAX
) {
848 * In an FTSENT, fts_pathlen is a u_short so it is
849 * possible to wraparound here. If we do, free up
850 * the current structure and the structures already
851 * allocated, then error out with ENAMETOOLONG.
855 (void)closedir(dirp
);
856 cur
->fts_info
= FTS_ERR
;
858 __set_errno (ENAMETOOLONG
);
861 p
->fts_level
= level
;
862 p
->fts_parent
= sp
->fts_cur
;
863 p
->fts_pathlen
= len
+ NAMLEN (dp
);
865 #if defined FTS_WHITEOUT && 0
866 if (dp
->d_type
== DT_WHT
)
867 p
->fts_flags
|= FTS_ISW
;
872 p
->fts_info
= FTS_NS
;
873 p
->fts_errno
= cderrno
;
875 p
->fts_info
= FTS_NSOK
;
876 p
->fts_accpath
= cur
->fts_accpath
;
877 } else if (nlinks
== 0
878 #if defined DT_DIR && defined _DIRENT_HAVE_D_TYPE
880 dp
->d_type
!= DT_DIR
&& dp
->d_type
!= DT_UNKNOWN
)
884 ISSET(FTS_NOCHDIR
) ? p
->fts_path
: p
->fts_name
;
885 p
->fts_info
= FTS_NSOK
;
887 /* Build a file name for fts_stat to stat. */
888 if (ISSET(FTS_NOCHDIR
)) {
889 p
->fts_accpath
= p
->fts_path
;
890 memmove(cp
, p
->fts_name
, p
->fts_namelen
+ 1);
892 p
->fts_accpath
= p
->fts_name
;
894 p
->fts_info
= fts_stat(sp
, p
, 0);
896 /* Decrement link count if applicable. */
897 if (nlinks
> 0 && (p
->fts_info
== FTS_D
||
898 p
->fts_info
== FTS_DC
|| p
->fts_info
== FTS_DOT
))
902 /* We walk in directory order so "ls -f" doesn't get upset. */
913 (void)closedir(dirp
);
916 * If realloc() changed the address of the path, adjust the
917 * addresses for the rest of the tree and the dir list.
920 fts_padjust(sp
, head
);
923 * If not changing directories, reset the path back to original
926 if (ISSET(FTS_NOCHDIR
)) {
927 if (len
== sp
->fts_pathlen
|| nitems
== 0)
933 * If descended after called from fts_children or after called from
934 * fts_read and nothing found, get back. At the root level we use
935 * the saved fd; if one of fts_open()'s arguments is a relative path
936 * to an empty directory, we wind up here with no other way back. If
937 * can't get back, we're done.
939 if (descend
&& (type
== BCHILD
|| !nitems
) &&
940 (cur
->fts_level
== FTS_ROOTLEVEL
?
941 FCHDIR(sp
, sp
->fts_rfd
) :
942 fts_safe_changedir(sp
, cur
->fts_parent
, -1, ".."))) {
943 cur
->fts_info
= FTS_ERR
;
948 /* If didn't find anything, return NULL. */
951 cur
->fts_info
= FTS_DP
;
955 /* Sort the entries. */
956 if (sp
->fts_compar
&& nitems
> 1)
957 head
= fts_sort(sp
, head
, nitems
);
963 fts_stat(sp
, p
, follow
)
968 struct stat
*sbp
, sb
;
971 /* If user needs stat info, stat buffer already allocated. */
972 sbp
= ISSET(FTS_NOSTAT
) ? &sb
: p
->fts_statp
;
974 #if defined FTS_WHITEOUT && 0
975 /* check for whiteout */
976 if (p
->fts_flags
& FTS_ISW
) {
978 memset(sbp
, '\0', sizeof (*sbp
));
979 sbp
->st_mode
= S_IFWHT
;
986 * If doing a logical walk, or application requested FTS_FOLLOW, do
987 * a stat(2). If that fails, check for a non-existent symlink. If
988 * fail, set the errno from the stat call.
990 if (ISSET(FTS_LOGICAL
) || follow
) {
991 if (stat(p
->fts_accpath
, sbp
)) {
993 if (!lstat(p
->fts_accpath
, sbp
)) {
997 p
->fts_errno
= saved_errno
;
1000 } else if (lstat(p
->fts_accpath
, sbp
)) {
1001 p
->fts_errno
= errno
;
1002 err
: memset(sbp
, 0, sizeof(struct stat
));
1006 if (S_ISDIR(sbp
->st_mode
)) {
1009 * Set the device/inode. Used to find cycles and check for
1010 * crossing mount points. Also remember the link count, used
1011 * in fts_build to limit the number of stat calls. It is
1012 * understood that these fields are only referenced if fts_info
1015 p
->fts_dev
= sbp
->st_dev
;
1016 p
->fts_ino
= sbp
->st_ino
;
1017 p
->fts_nlink
= sbp
->st_nlink
;
1019 if (ISDOT(p
->fts_name
))
1023 * See if we've already encountered this directory.
1024 * This can happen when following symlinks as well as
1025 * with a corrupted directory hierarchy.
1027 if ((t
= find_object (sp
, sbp
))) {
1032 /* Remember the object, ignoring any failure. If we're running
1033 out of memory, detecting cycles isn't a high priority. */
1034 add_object (sp
, p
, sbp
);
1038 if (S_ISLNK(sbp
->st_mode
))
1040 if (S_ISREG(sbp
->st_mode
))
1042 return (FTS_DEFAULT
);
1047 fts_sort(sp
, head
, nitems
)
1050 register int nitems
;
1052 register FTSENT
**ap
, *p
;
1055 * Construct an array of pointers to the structures and call qsort(3).
1056 * Reassemble the array in the order returned by qsort. If unable to
1057 * sort for memory reasons, return the directory entries in their
1058 * current order. Allocate enough space for the current needs plus
1059 * 40 so don't realloc one entry at a time.
1061 if (nitems
> sp
->fts_nitems
) {
1064 sp
->fts_nitems
= nitems
+ 40;
1065 if ((a
= realloc(sp
->fts_array
,
1066 (size_t)(sp
->fts_nitems
* sizeof(FTSENT
*)))) == NULL
) {
1067 free(sp
->fts_array
);
1068 sp
->fts_array
= NULL
;
1074 for (ap
= sp
->fts_array
, p
= head
; p
; p
= p
->fts_link
)
1076 qsort((void *)sp
->fts_array
, nitems
, sizeof(FTSENT
*), sp
->fts_compar
);
1077 for (head
= *(ap
= sp
->fts_array
); --nitems
; ++ap
)
1078 ap
[0]->fts_link
= ap
[1];
1079 ap
[0]->fts_link
= NULL
;
1085 fts_alloc(sp
, name
, namelen
)
1088 register int namelen
;
1094 * The file name is a variable length array and no stat structure is
1095 * necessary if the user has set the nostat bit. Allocate the FTSENT
1096 * structure, the file name and the stat structure in one chunk, but
1097 * be careful that the stat structure is reasonably aligned. Since the
1098 * fts_name field is declared to be of size 1, the fts_name pointer is
1099 * namelen + 2 before the first possible address of the stat structure.
1101 len
= sizeof(FTSENT
) + namelen
;
1102 if (!ISSET(FTS_NOSTAT
))
1103 len
+= sizeof(struct stat
) + ALIGNBYTES
;
1104 if ((p
= malloc(len
)) == NULL
)
1107 /* Copy the name and guarantee NUL termination. */
1108 memmove(p
->fts_name
, name
, namelen
);
1109 p
->fts_name
[namelen
] = '\0';
1111 if (!ISSET(FTS_NOSTAT
))
1112 p
->fts_statp
= (struct stat
*)ALIGN(p
->fts_name
+ namelen
+ 2);
1113 p
->fts_namelen
= namelen
;
1114 p
->fts_path
= sp
->fts_path
;
1117 p
->fts_instr
= FTS_NOINSTR
;
1119 p
->fts_pointer
= NULL
;
1126 register FTSENT
*head
;
1130 /* Free a linked list of structures. */
1131 while ((p
= head
)) {
1132 head
= head
->fts_link
;
1138 * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
1139 * Most systems will allow creation of paths much longer than MAXPATHLEN, even
1140 * though the kernel won't resolve them. Add the size (not just what's needed)
1141 * plus 256 bytes so don't realloc the path 2 bytes at a time.
1145 fts_palloc(sp
, more
)
1151 sp
->fts_pathlen
+= more
+ 256;
1153 * Check for possible wraparound. In an FTS, fts_pathlen is
1154 * a signed int but in an FTSENT it is an unsigned short.
1155 * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
1157 if (sp
->fts_pathlen
< 0 || sp
->fts_pathlen
>= USHRT_MAX
) {
1160 sp
->fts_path
= NULL
;
1162 sp
->fts_path
= NULL
;
1163 __set_errno (ENAMETOOLONG
);
1166 p
= realloc(sp
->fts_path
, sp
->fts_pathlen
);
1169 sp
->fts_path
= NULL
;
1177 * When the path is realloc'd, have to fix all of the pointers in structures
1182 fts_padjust(sp
, head
)
1187 char *addr
= sp
->fts_path
;
1189 #define ADJUST(p) do { \
1190 if ((p)->fts_accpath != (p)->fts_name) { \
1191 (p)->fts_accpath = \
1192 (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
1194 (p)->fts_path = addr; \
1196 /* Adjust the current set of children. */
1197 for (p
= sp
->fts_child
; p
; p
= p
->fts_link
)
1200 /* Adjust the rest of the tree, including the current level. */
1201 for (p
= head
; p
->fts_level
>= FTS_ROOTLEVEL
;) {
1203 p
= p
->fts_link
? p
->fts_link
: p
->fts_parent
;
1214 for (max
= 0; *argv
; ++argv
)
1215 if ((len
= strlen(*argv
)) > max
)
1221 * Change to dir specified by fd or p->fts_accpath without getting
1222 * tricked by someone changing the world out from underneath us.
1223 * Assumes p->fts_dev and p->fts_ino are filled in.
1227 fts_safe_changedir(sp
, p
, fd
, path
)
1233 int ret
, oerrno
, newfd
;
1237 if (ISSET(FTS_NOCHDIR
))
1239 if (fd
< 0 && (newfd
= open(path
, O_RDONLY
, 0)) < 0)
1241 if (__fxstat64(_STAT_VER
, newfd
, &sb
)) {
1245 if (p
->fts_dev
!= sb
.st_dev
|| p
->fts_ino
!= sb
.st_ino
) {
1246 __set_errno (ENOENT
); /* disinformation */
1250 ret
= fchdir(newfd
);
1255 __set_errno (oerrno
);