fts: arrange not to stat non-directories in more cases
[gnulib.git] / lib / fts.c
1 /* Traverse a file hierarchy.
2
3    Copyright (C) 2004-2009 Free Software Foundation, Inc.
4
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 3 of the License, or
8    (at your option) any later version.
9
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.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 /*-
19  * Copyright (c) 1990, 1993, 1994
20  *      The Regents of the University of California.  All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 4. Neither the name of the University nor the names of its contributors
31  *    may be used to endorse or promote products derived from this software
32  *    without specific prior written permission.
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44  * SUCH DAMAGE.
45  */
46
47 #include <config.h>
48
49 #if defined(LIBC_SCCS) && !defined(lint)
50 static char sccsid[] = "@(#)fts.c       8.6 (Berkeley) 8/14/94";
51 #endif /* LIBC_SCCS and not lint */
52
53 #include "fts_.h"
54
55 #if HAVE_SYS_PARAM_H || defined _LIBC
56 # include <sys/param.h>
57 #endif
58 #ifdef _LIBC
59 # include <include/sys/stat.h>
60 #else
61 # include <sys/stat.h>
62 #endif
63 #include <fcntl.h>
64 #include <errno.h>
65 #include <stdbool.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <unistd.h>
69
70 #if ! _LIBC
71 # include "fcntl--.h"
72 # include "openat.h"
73 # include "unistd--.h"
74 # include "same-inode.h"
75 #endif
76
77 #include <dirent.h>
78 #ifndef _D_EXACT_NAMLEN
79 # define _D_EXACT_NAMLEN(dirent) strlen ((dirent)->d_name)
80 #endif
81
82 #if HAVE_STRUCT_DIRENT_D_TYPE
83 /* True if the type of the directory entry D is known.  */
84 # define DT_IS_KNOWN(d) ((d)->d_type != DT_UNKNOWN)
85 /* True if the type of the directory entry D must be T.  */
86 # define DT_MUST_BE(d, t) ((d)->d_type == (t))
87 # define D_TYPE(d) ((d)->d_type)
88 #else
89 # define DT_IS_KNOWN(d) false
90 # define DT_MUST_BE(d, t) false
91 # define D_TYPE(d) DT_UNKNOWN
92
93 # undef DT_UNKNOWN
94 # define DT_UNKNOWN 0
95
96 /* Any nonzero values will do here, so long as they're distinct.
97    Undef any existing macros out of the way.  */
98 # undef DT_BLK
99 # undef DT_CHR
100 # undef DT_DIR
101 # undef DT_FIFO
102 # undef DT_LNK
103 # undef DT_REG
104 # undef DT_SOCK
105 # define DT_BLK 1
106 # define DT_CHR 2
107 # define DT_DIR 3
108 # define DT_FIFO 4
109 # define DT_LNK 5
110 # define DT_REG 6
111 # define DT_SOCK 7
112 #endif
113
114 #ifndef S_IFLNK
115 # define S_IFLNK 0
116 #endif
117 #ifndef S_IFSOCK
118 # define S_IFSOCK 0
119 #endif
120
121 enum
122 {
123   NOT_AN_INODE_NUMBER = 0
124 };
125
126 #ifdef D_INO_IN_DIRENT
127 # define D_INO(dp) (dp)->d_ino
128 #else
129 /* Some systems don't have inodes, so fake them to avoid lots of ifdefs.  */
130 # define D_INO(dp) NOT_AN_INODE_NUMBER
131 #endif
132
133 /* If there are more than this many entries in a directory,
134    and the conditions mentioned below are satisfied, then sort
135    the entries on inode number before any further processing.  */
136 #ifndef FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
137 # define FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD 10000
138 #endif
139 enum
140 {
141   _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD = FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
142 };
143
144 enum Fts_stat
145 {
146   FTS_NO_STAT_REQUIRED = 1,
147   FTS_STAT_REQUIRED = 2
148 };
149
150 #ifdef _LIBC
151 # undef close
152 # define close __close
153 # undef closedir
154 # define closedir __closedir
155 # undef fchdir
156 # define fchdir __fchdir
157 # undef open
158 # define open __open
159 # undef opendir
160 # define opendir __opendir
161 # undef readdir
162 # define readdir __readdir
163 #else
164 # undef internal_function
165 # define internal_function /* empty */
166 #endif
167
168 #ifndef __set_errno
169 # define __set_errno(Val) errno = (Val)
170 #endif
171
172 #ifndef __attribute__
173 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
174 #  define __attribute__(x) /* empty */
175 # endif
176 #endif
177
178 #ifndef ATTRIBUTE_UNUSED
179 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
180 #endif
181
182 /* If this host provides the openat function, then we can avoid
183    attempting to open "." in some initialization code below.  */
184 #ifdef HAVE_OPENAT
185 # define HAVE_OPENAT_SUPPORT 1
186 #else
187 # define HAVE_OPENAT_SUPPORT 0
188 #endif
189
190 #ifdef NDEBUG
191 # define fts_assert(expr) ((void) 0)
192 #else
193 # define fts_assert(expr)       \
194     do                          \
195       {                         \
196         if (!(expr))            \
197           abort ();             \
198       }                         \
199     while (false)
200 #endif
201
202 static FTSENT   *fts_alloc (FTS *, const char *, size_t) internal_function;
203 static FTSENT   *fts_build (FTS *, int) internal_function;
204 static void      fts_lfree (FTSENT *) internal_function;
205 static void      fts_load (FTS *, FTSENT *) internal_function;
206 static size_t    fts_maxarglen (char * const *) internal_function;
207 static void      fts_padjust (FTS *, FTSENT *) internal_function;
208 static bool      fts_palloc (FTS *, size_t) internal_function;
209 static FTSENT   *fts_sort (FTS *, FTSENT *, size_t) internal_function;
210 static unsigned short int fts_stat (FTS *, FTSENT *, bool) internal_function;
211 static int      fts_safe_changedir (FTS *, FTSENT *, int, const char *)
212      internal_function;
213
214 #if GNULIB_FTS
215 # include "fts-cycle.c"
216 #else
217 static bool enter_dir (FTS *fts, FTSENT *ent) { return true; }
218 static void leave_dir (FTS *fts, FTSENT *ent) {}
219 static bool setup_dir (FTS *fts) { return true; }
220 static void free_dir (FTS *fts) {}
221 #endif
222
223 #ifndef MAX
224 # define MAX(a,b) ((a) > (b) ? (a) : (b))
225 #endif
226
227 #ifndef SIZE_MAX
228 # define SIZE_MAX ((size_t) -1)
229 #endif
230
231 #ifndef O_DIRECTORY
232 # define O_DIRECTORY 0
233 #endif
234
235 #define ISDOT(a)        (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
236 #define STREQ(a, b)     (strcmp ((a), (b)) == 0)
237
238 #define CLR(opt)        (sp->fts_options &= ~(opt))
239 #define ISSET(opt)      (sp->fts_options & (opt))
240 #define SET(opt)        (sp->fts_options |= (opt))
241
242 /* FIXME: make this a function */
243 #define RESTORE_INITIAL_CWD(sp)                 \
244   (fd_ring_clear (&((sp)->fts_fd_ring)),        \
245    FCHDIR ((sp), (ISSET (FTS_CWDFD) ? AT_FDCWD : (sp)->fts_rfd)))
246
247 /* FIXME: FTS_NOCHDIR is now misnamed.
248    Call it FTS_USE_FULL_RELATIVE_FILE_NAMES instead. */
249 #define FCHDIR(sp, fd)                                  \
250   (!ISSET(FTS_NOCHDIR) && (ISSET(FTS_CWDFD)             \
251                            ? (cwd_advance_fd ((sp), (fd), true), 0) \
252                            : fchdir (fd)))
253
254
255 /* fts_build flags */
256 /* FIXME: make this an enum */
257 #define BCHILD          1               /* fts_children */
258 #define BNAMES          2               /* fts_children, names only */
259 #define BREAD           3               /* fts_read */
260
261 #if FTS_DEBUG
262 # include <inttypes.h>
263 # include <stdint.h>
264 # include <stdio.h>
265 # include "getcwdat.h"
266 bool fts_debug = false;
267 # define Dprintf(x) do { if (fts_debug) printf x; } while (false)
268 #else
269 # define Dprintf(x)
270 # define fd_ring_check(x)
271 # define fd_ring_print(a, b, c)
272 #endif
273
274 #define LEAVE_DIR(Fts, Ent, Tag)                                \
275   do                                                            \
276     {                                                           \
277       Dprintf (("  %s-leaving: %s\n", Tag, (Ent)->fts_path));   \
278       leave_dir (Fts, Ent);                                     \
279       fd_ring_check (Fts);                                      \
280     }                                                           \
281   while (false)
282
283 static void
284 fd_ring_clear (I_ring *fd_ring)
285 {
286   while ( ! i_ring_empty (fd_ring))
287     {
288       int fd = i_ring_pop (fd_ring);
289       if (0 <= fd)
290         close (fd);
291     }
292 }
293
294 /* Overload the fts_statp->st_size member (otherwise unused, when
295    fts_info is FTS_NSOK) to indicate whether fts_read should stat
296    this entry or not.  */
297 static void
298 fts_set_stat_required (FTSENT *p, bool required)
299 {
300   fts_assert (p->fts_info == FTS_NSOK);
301   p->fts_statp->st_size = (required
302                            ? FTS_STAT_REQUIRED
303                            : FTS_NO_STAT_REQUIRED);
304 }
305
306 /* file-descriptor-relative opendir.  */
307 /* FIXME: if others need this function, move it into lib/openat.c */
308 static inline DIR *
309 internal_function
310 opendirat (int fd, char const *dir)
311 {
312   int new_fd = openat (fd, dir, O_RDONLY);
313   DIR *dirp;
314
315   if (new_fd < 0)
316     return NULL;
317   dirp = fdopendir (new_fd);
318   if (dirp == NULL)
319     {
320       int saved_errno = errno;
321       close (new_fd);
322       errno = saved_errno;
323     }
324   return dirp;
325 }
326
327 /* Virtual fchdir.  Advance SP's working directory file descriptor,
328    SP->fts_cwd_fd, to FD, and push the previous value onto the fd_ring.
329    CHDIR_DOWN_ONE is true if FD corresponds to an entry in the directory
330    open on sp->fts_cwd_fd; i.e., to move the working directory one level
331    down.  */
332 static void
333 internal_function
334 cwd_advance_fd (FTS *sp, int fd, bool chdir_down_one)
335 {
336   int old = sp->fts_cwd_fd;
337   fts_assert (old != fd || old == AT_FDCWD);
338
339   if (chdir_down_one)
340     {
341       /* Push "old" onto the ring.
342          If the displaced file descriptor is non-negative, close it.  */
343       int prev_fd_in_slot = i_ring_push (&sp->fts_fd_ring, old);
344       fd_ring_print (sp, stderr, "post-push");
345       if (0 <= prev_fd_in_slot)
346         close (prev_fd_in_slot); /* ignore any close failure */
347     }
348   else if ( ! ISSET (FTS_NOCHDIR))
349     {
350       if (0 <= old)
351         close (old); /* ignore any close failure */
352     }
353
354   sp->fts_cwd_fd = fd;
355 }
356
357 /* Open the directory DIR if possible, and return a file
358    descriptor.  Return -1 and set errno on failure.  It doesn't matter
359    whether the file descriptor has read or write access.  */
360
361 static inline int
362 internal_function
363 diropen (FTS const *sp, char const *dir)
364 {
365   int open_flags = (O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
366                     | (ISSET (FTS_PHYSICAL) ? O_NOFOLLOW : 0));
367
368   return (ISSET (FTS_CWDFD)
369           ? openat (sp->fts_cwd_fd, dir, open_flags)
370           : open (dir, open_flags));
371 }
372
373 FTS *
374 fts_open (char * const *argv,
375           register int options,
376           int (*compar) (FTSENT const **, FTSENT const **))
377 {
378         register FTS *sp;
379         register FTSENT *p, *root;
380         register size_t nitems;
381         FTSENT *parent = NULL;
382         FTSENT *tmp = NULL;     /* pacify gcc */
383         size_t len;
384         bool defer_stat;
385
386         /* Options check. */
387         if (options & ~FTS_OPTIONMASK) {
388                 __set_errno (EINVAL);
389                 return (NULL);
390         }
391         if ((options & FTS_NOCHDIR) && (options & FTS_CWDFD)) {
392                 __set_errno (EINVAL);
393                 return (NULL);
394         }
395         if ( ! (options & (FTS_LOGICAL | FTS_PHYSICAL))) {
396                 __set_errno (EINVAL);
397                 return (NULL);
398         }
399
400         /* Allocate/initialize the stream */
401         if ((sp = malloc(sizeof(FTS))) == NULL)
402                 return (NULL);
403         memset(sp, 0, sizeof(FTS));
404         sp->fts_compar = compar;
405         sp->fts_options = options;
406
407         /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
408         if (ISSET(FTS_LOGICAL)) {
409                 SET(FTS_NOCHDIR);
410                 CLR(FTS_CWDFD);
411         }
412
413         /* Initialize fts_cwd_fd.  */
414         sp->fts_cwd_fd = AT_FDCWD;
415         if ( ISSET(FTS_CWDFD) && ! HAVE_OPENAT_SUPPORT)
416           {
417             /* While it isn't technically necessary to open "." this
418                early, doing it here saves us the trouble of ensuring
419                later (where it'd be messier) that "." can in fact
420                be opened.  If not, revert to FTS_NOCHDIR mode.  */
421             int fd = open (".", O_RDONLY);
422             if (fd < 0)
423               {
424                 /* Even if `.' is unreadable, don't revert to FTS_NOCHDIR mode
425                    on systems like Linux+PROC_FS, where our openat emulation
426                    is good enough.  Note: on a system that emulates
427                    openat via /proc, this technique can still fail, but
428                    only in extreme conditions, e.g., when the working
429                    directory cannot be saved (i.e. save_cwd fails) --
430                    and that happens on Linux only when "." is unreadable
431                    and the CWD would be longer than PATH_MAX.
432                    FIXME: once Linux kernel openat support is well established,
433                    replace the above open call and this entire if/else block
434                    with the body of the if-block below.  */
435                 if ( openat_needs_fchdir ())
436                   {
437                     SET(FTS_NOCHDIR);
438                     CLR(FTS_CWDFD);
439                   }
440               }
441             else
442               {
443                 close (fd);
444               }
445           }
446
447         /*
448          * Start out with 1K of file name space, and enough, in any case,
449          * to hold the user's file names.
450          */
451 #ifndef MAXPATHLEN
452 # define MAXPATHLEN 1024
453 #endif
454         {
455           size_t maxarglen = fts_maxarglen(argv);
456           if (! fts_palloc(sp, MAX(maxarglen, MAXPATHLEN)))
457                   goto mem1;
458         }
459
460         /* Allocate/initialize root's parent. */
461         if (*argv != NULL) {
462                 if ((parent = fts_alloc(sp, "", 0)) == NULL)
463                         goto mem2;
464                 parent->fts_level = FTS_ROOTPARENTLEVEL;
465           }
466
467         /* The classic fts implementation would call fts_stat with
468            a new entry for each iteration of the loop below.
469            If the comparison function is not specified or if the
470            FTS_DEFER_STAT option is in effect, don't stat any entry
471            in this loop.  This is an attempt to minimize the interval
472            between the initial stat/lstat/fstatat and the point at which
473            a directory argument is first opened.  This matters for any
474            directory command line argument that resides on a file system
475            without genuine i-nodes.  If you specify FTS_DEFER_STAT along
476            with a comparison function, that function must not access any
477            data via the fts_statp pointer.  */
478         defer_stat = (compar == NULL || ISSET(FTS_DEFER_STAT));
479
480         /* Allocate/initialize root(s). */
481         for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
482                 /* Don't allow zero-length file names. */
483                 if ((len = strlen(*argv)) == 0) {
484                         __set_errno (ENOENT);
485                         goto mem3;
486                 }
487
488                 if ((p = fts_alloc(sp, *argv, len)) == NULL)
489                         goto mem3;
490                 p->fts_level = FTS_ROOTLEVEL;
491                 p->fts_parent = parent;
492                 p->fts_accpath = p->fts_name;
493                 /* Even when defer_stat is true, be sure to stat the first
494                    command line argument, since fts_read (at least with
495                    FTS_XDEV) requires that.  */
496                 if (defer_stat && root != NULL) {
497                         p->fts_info = FTS_NSOK;
498                         fts_set_stat_required(p, true);
499                 } else {
500                         p->fts_info = fts_stat(sp, p, false);
501                 }
502
503                 /*
504                  * If comparison routine supplied, traverse in sorted
505                  * order; otherwise traverse in the order specified.
506                  */
507                 if (compar) {
508                         p->fts_link = root;
509                         root = p;
510                 } else {
511                         p->fts_link = NULL;
512                         if (root == NULL)
513                                 tmp = root = p;
514                         else {
515                                 tmp->fts_link = p;
516                                 tmp = p;
517                         }
518                 }
519         }
520         if (compar && nitems > 1)
521                 root = fts_sort(sp, root, nitems);
522
523         /*
524          * Allocate a dummy pointer and make fts_read think that we've just
525          * finished the node before the root(s); set p->fts_info to FTS_INIT
526          * so that everything about the "current" node is ignored.
527          */
528         if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
529                 goto mem3;
530         sp->fts_cur->fts_link = root;
531         sp->fts_cur->fts_info = FTS_INIT;
532         if (! setup_dir (sp))
533                 goto mem3;
534
535         /*
536          * If using chdir(2), grab a file descriptor pointing to dot to ensure
537          * that we can get back here; this could be avoided for some file names,
538          * but almost certainly not worth the effort.  Slashes, symbolic links,
539          * and ".." are all fairly nasty problems.  Note, if we can't get the
540          * descriptor we run anyway, just more slowly.
541          */
542         if (!ISSET(FTS_NOCHDIR) && !ISSET(FTS_CWDFD)
543             && (sp->fts_rfd = diropen (sp, ".")) < 0)
544                 SET(FTS_NOCHDIR);
545
546         i_ring_init (&sp->fts_fd_ring, -1);
547         return (sp);
548
549 mem3:   fts_lfree(root);
550         free(parent);
551 mem2:   free(sp->fts_path);
552 mem1:   free(sp);
553         return (NULL);
554 }
555
556 static void
557 internal_function
558 fts_load (FTS *sp, register FTSENT *p)
559 {
560         register size_t len;
561         register char *cp;
562
563         /*
564          * Load the stream structure for the next traversal.  Since we don't
565          * actually enter the directory until after the preorder visit, set
566          * the fts_accpath field specially so the chdir gets done to the right
567          * place and the user can access the first node.  From fts_open it's
568          * known that the file name will fit.
569          */
570         len = p->fts_pathlen = p->fts_namelen;
571         memmove(sp->fts_path, p->fts_name, len + 1);
572         if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
573                 len = strlen(++cp);
574                 memmove(p->fts_name, cp, len + 1);
575                 p->fts_namelen = len;
576         }
577         p->fts_accpath = p->fts_path = sp->fts_path;
578 }
579
580 int
581 fts_close (FTS *sp)
582 {
583         register FTSENT *freep, *p;
584         int saved_errno = 0;
585
586         /*
587          * This still works if we haven't read anything -- the dummy structure
588          * points to the root list, so we step through to the end of the root
589          * list which has a valid parent pointer.
590          */
591         if (sp->fts_cur) {
592                 for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
593                         freep = p;
594                         p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
595                         free(freep);
596                 }
597                 free(p);
598         }
599
600         /* Free up child linked list, sort array, file name buffer. */
601         if (sp->fts_child)
602                 fts_lfree(sp->fts_child);
603         free(sp->fts_array);
604         free(sp->fts_path);
605
606         if (ISSET(FTS_CWDFD))
607           {
608             if (0 <= sp->fts_cwd_fd)
609               close (sp->fts_cwd_fd);
610           }
611         else if (!ISSET(FTS_NOCHDIR))
612           {
613             /* Return to original directory, save errno if necessary. */
614             if (fchdir(sp->fts_rfd))
615               saved_errno = errno;
616             close(sp->fts_rfd);
617           }
618
619         fd_ring_clear (&sp->fts_fd_ring);
620
621         if (sp->fts_leaf_optimization_works_ht)
622           hash_free (sp->fts_leaf_optimization_works_ht);
623
624         free_dir (sp);
625
626         /* Free up the stream pointer. */
627         free(sp);
628
629         /* Set errno and return. */
630         if (saved_errno) {
631                 __set_errno (saved_errno);
632                 return (-1);
633         }
634
635         return (0);
636 }
637
638 #if defined __linux__ \
639   && HAVE_SYS_VFS_H && HAVE_FSTATFS && HAVE_STRUCT_STATFS_F_TYPE
640
641 #include <sys/vfs.h>
642
643 /* Linux-specific constants from coreutils' src/fs.h */
644 # define S_MAGIC_TMPFS 0x1021994
645 # define S_MAGIC_NFS 0x6969
646 # define S_MAGIC_REISERFS 0x52654973
647 # define S_MAGIC_PROC 0x9FA0
648
649 /* Return false if it is easy to determine the file system type of
650    the directory on which DIR_FD is open, and sorting dirents on
651    inode numbers is known not to improve traversal performance with
652    that type of file system.  Otherwise, return true.  */
653 static bool
654 dirent_inode_sort_may_be_useful (int dir_fd)
655 {
656   /* Skip the sort only if we can determine efficiently
657      that skipping it is the right thing to do.
658      The cost of performing an unnecessary sort is negligible,
659      while the cost of *not* performing it can be O(N^2) with
660      a very large constant.  */
661   struct statfs fs_buf;
662
663   /* If fstatfs fails, assume sorting would be useful.  */
664   if (fstatfs (dir_fd, &fs_buf) != 0)
665     return true;
666
667   /* FIXME: what about when f_type is not an integral type?
668      deal with that if/when it's encountered.  */
669   switch (fs_buf.f_type)
670     {
671     case S_MAGIC_TMPFS:
672     case S_MAGIC_NFS:
673       /* On a file system of any of these types, sorting
674          is unnecessary, and hence wasteful.  */
675       return false;
676
677     default:
678       return true;
679     }
680 }
681
682 /* Given a file descriptor DIR_FD open on a directory D,
683    return true if it is valid to apply the leaf-optimization
684    technique of counting directories in D via stat.st_nlink.  */
685 static bool
686 leaf_optimization_applies (int dir_fd)
687 {
688   struct statfs fs_buf;
689
690   /* If fstatfs fails, assume we can't use the optimization.  */
691   if (fstatfs (dir_fd, &fs_buf) != 0)
692     return false;
693
694   /* FIXME: do we need to detect AFS mount points?  I doubt it,
695      unless fstatfs can report S_MAGIC_REISERFS for such a directory.  */
696
697   switch (fs_buf.f_type)
698     {
699       /* List here the file system types that lack useable dirent.d_type
700          info, yet for which the optimization does apply.  */
701     case S_MAGIC_REISERFS:
702       return true;
703
704     case S_MAGIC_PROC:
705       /* Explicitly listing this or any other file system type for which
706          the optimization is not applicable is not necessary, but we leave
707          it here to document the risk.  Per http://bugs.debian.org/143111,
708          /proc may have bogus stat.st_nlink values.  */
709       /* fall through */
710     default:
711       return false;
712     }
713 }
714
715 #else
716 static bool dirent_inode_sort_may_be_useful (int dir_fd) { return true; }
717 static bool leaf_optimization_applies (int dir_fd) { return false; }
718 #endif
719
720 /* link-count-optimization entry:
721    map an stat.st_dev number to a boolean: leaf_optimization_works */
722 struct LCO_ent
723 {
724   dev_t st_dev;
725   bool opt_ok;
726 };
727
728 /* Use a tiny initial size.  If a traversal encounters more than
729    a few devices, the cost of growing/rehashing this table will be
730    rendered negligible by the number of inodes processed.  */
731 enum { LCO_HT_INITIAL_SIZE = 13 };
732
733 static size_t
734 LCO_hash (void const *x, size_t table_size)
735 {
736   struct LCO_ent const *ax = x;
737   return (uintmax_t) ax->st_dev % table_size;
738 }
739
740 static bool
741 LCO_compare (void const *x, void const *y)
742 {
743   struct LCO_ent const *ax = x;
744   struct LCO_ent const *ay = y;
745   return ax->st_dev == ay->st_dev;
746 }
747
748 /* Ask the same question as leaf_optimization_applies, but query
749    the cache first (FTS.fts_leaf_optimization_works_ht), and if necessary,
750    update that cache.  */
751 static bool
752 link_count_optimize_ok (FTSENT const *p)
753 {
754   FTS *sp = p->fts_fts;
755   Hash_table *h = sp->fts_leaf_optimization_works_ht;
756   struct LCO_ent tmp;
757   struct LCO_ent *ent;
758   bool opt_ok;
759   struct LCO_ent *t2;
760
761   /* If we're not in CWDFD mode, don't bother with this optimization,
762      since the caller is not serious about performance. */
763   if (!ISSET(FTS_CWDFD))
764     return false;
765
766   /* map st_dev to the boolean, leaf_optimization_works */
767   if (h == NULL)
768     {
769       h = sp->fts_leaf_optimization_works_ht
770         = hash_initialize (LCO_HT_INITIAL_SIZE, NULL, LCO_hash,
771                            LCO_compare, free);
772       if (h == NULL)
773         return false;
774     }
775   tmp.st_dev = p->fts_statp->st_dev;
776   ent = hash_lookup (h, &tmp);
777   if (ent)
778     return ent->opt_ok;
779
780   /* Look-up failed.  Query directly and cache the result.  */
781   t2 = malloc (sizeof *t2);
782   if (t2 == NULL)
783     return false;
784
785   /* Is it ok to perform the optimization in the dir, FTS_CWD_FD?  */
786   opt_ok = leaf_optimization_applies (sp->fts_cwd_fd);
787   t2->opt_ok = opt_ok;
788   t2->st_dev = p->fts_statp->st_dev;
789
790   ent = hash_insert (h, t2);
791   if (ent == NULL)
792     {
793       /* insertion failed */
794       free (t2);
795       return false;
796     }
797   fts_assert (ent == t2);
798
799   return opt_ok;
800 }
801
802 /*
803  * Special case of "/" at the end of the file name so that slashes aren't
804  * appended which would cause file names to be written as "....//foo".
805  */
806 #define NAPPEND(p)                                                      \
807         (p->fts_path[p->fts_pathlen - 1] == '/'                         \
808             ? p->fts_pathlen - 1 : p->fts_pathlen)
809
810 FTSENT *
811 fts_read (register FTS *sp)
812 {
813         register FTSENT *p, *tmp;
814         register unsigned short int instr;
815         register char *t;
816
817         /* If finished or unrecoverable error, return NULL. */
818         if (sp->fts_cur == NULL || ISSET(FTS_STOP))
819                 return (NULL);
820
821         /* Set current node pointer. */
822         p = sp->fts_cur;
823
824         /* Save and zero out user instructions. */
825         instr = p->fts_instr;
826         p->fts_instr = FTS_NOINSTR;
827
828         /* Any type of file may be re-visited; re-stat and re-turn. */
829         if (instr == FTS_AGAIN) {
830                 p->fts_info = fts_stat(sp, p, false);
831                 return (p);
832         }
833         Dprintf (("fts_read: p=%s\n",
834                   p->fts_info == FTS_INIT ? "" : p->fts_path));
835
836         /*
837          * Following a symlink -- SLNONE test allows application to see
838          * SLNONE and recover.  If indirecting through a symlink, have
839          * keep a pointer to current location.  If unable to get that
840          * pointer, follow fails.
841          */
842         if (instr == FTS_FOLLOW &&
843             (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
844                 p->fts_info = fts_stat(sp, p, true);
845                 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
846                         if ((p->fts_symfd = diropen (sp, ".")) < 0) {
847                                 p->fts_errno = errno;
848                                 p->fts_info = FTS_ERR;
849                         } else
850                                 p->fts_flags |= FTS_SYMFOLLOW;
851                 }
852                 goto check_for_dir;
853         }
854
855         /* Directory in pre-order. */
856         if (p->fts_info == FTS_D) {
857                 /* If skipped or crossed mount point, do post-order visit. */
858                 if (instr == FTS_SKIP ||
859                     (ISSET(FTS_XDEV) && p->fts_statp->st_dev != sp->fts_dev)) {
860                         if (p->fts_flags & FTS_SYMFOLLOW)
861                                 (void)close(p->fts_symfd);
862                         if (sp->fts_child) {
863                                 fts_lfree(sp->fts_child);
864                                 sp->fts_child = NULL;
865                         }
866                         p->fts_info = FTS_DP;
867                         LEAVE_DIR (sp, p, "1");
868                         return (p);
869                 }
870
871                 /* Rebuild if only read the names and now traversing. */
872                 if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
873                         CLR(FTS_NAMEONLY);
874                         fts_lfree(sp->fts_child);
875                         sp->fts_child = NULL;
876                 }
877
878                 /*
879                  * Cd to the subdirectory.
880                  *
881                  * If have already read and now fail to chdir, whack the list
882                  * to make the names come out right, and set the parent errno
883                  * so the application will eventually get an error condition.
884                  * Set the FTS_DONTCHDIR flag so that when we logically change
885                  * directories back to the parent we don't do a chdir.
886                  *
887                  * If haven't read do so.  If the read fails, fts_build sets
888                  * FTS_STOP or the fts_info field of the node.
889                  */
890                 if (sp->fts_child != NULL) {
891                         if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
892                                 p->fts_errno = errno;
893                                 p->fts_flags |= FTS_DONTCHDIR;
894                                 for (p = sp->fts_child; p != NULL;
895                                      p = p->fts_link)
896                                         p->fts_accpath =
897                                             p->fts_parent->fts_accpath;
898                         }
899                 } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
900                         if (ISSET(FTS_STOP))
901                                 return (NULL);
902                         /* If fts_build's call to fts_safe_changedir failed
903                            because it was not able to fchdir into a
904                            subdirectory, tell the caller.  */
905                         if (p->fts_errno && p->fts_info != FTS_DNR)
906                                 p->fts_info = FTS_ERR;
907                         LEAVE_DIR (sp, p, "2");
908                         return (p);
909                 }
910                 p = sp->fts_child;
911                 sp->fts_child = NULL;
912                 goto name;
913         }
914
915         /* Move to the next node on this level. */
916 next:   tmp = p;
917         if ((p = p->fts_link) != NULL) {
918                 sp->fts_cur = p;
919                 free(tmp);
920
921                 /*
922                  * If reached the top, return to the original directory (or
923                  * the root of the tree), and load the file names for the next
924                  * root.
925                  */
926                 if (p->fts_level == FTS_ROOTLEVEL) {
927                         if (RESTORE_INITIAL_CWD(sp)) {
928                                 SET(FTS_STOP);
929                                 return (NULL);
930                         }
931                         fts_load(sp, p);
932                         goto check_for_dir;
933                 }
934
935                 /*
936                  * User may have called fts_set on the node.  If skipped,
937                  * ignore.  If followed, get a file descriptor so we can
938                  * get back if necessary.
939                  */
940                 if (p->fts_instr == FTS_SKIP)
941                         goto next;
942                 if (p->fts_instr == FTS_FOLLOW) {
943                         p->fts_info = fts_stat(sp, p, true);
944                         if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
945                                 if ((p->fts_symfd = diropen (sp, ".")) < 0) {
946                                         p->fts_errno = errno;
947                                         p->fts_info = FTS_ERR;
948                                 } else
949                                         p->fts_flags |= FTS_SYMFOLLOW;
950                         }
951                         p->fts_instr = FTS_NOINSTR;
952                 }
953
954 name:           t = sp->fts_path + NAPPEND(p->fts_parent);
955                 *t++ = '/';
956                 memmove(t, p->fts_name, p->fts_namelen + 1);
957 check_for_dir:
958                 sp->fts_cur = p;
959                 if (p->fts_info == FTS_NSOK)
960                   {
961                     if (p->fts_statp->st_size == FTS_STAT_REQUIRED)
962                       {
963                         FTSENT *parent = p->fts_parent;
964                         if (parent->fts_n_dirs_remaining == 0
965                             && ISSET(FTS_NOSTAT)
966                             && ISSET(FTS_PHYSICAL)
967                             && link_count_optimize_ok (parent))
968                           {
969                             /* nothing more needed */
970                           }
971                         else
972                           {
973                             p->fts_info = fts_stat(sp, p, false);
974                             if (S_ISDIR(p->fts_statp->st_mode))
975                               {
976                                 if (parent->fts_n_dirs_remaining)
977                                   parent->fts_n_dirs_remaining--;
978                               }
979                           }
980                       }
981                     else
982                       fts_assert (p->fts_statp->st_size == FTS_NO_STAT_REQUIRED);
983                   }
984
985                 if (p->fts_info == FTS_D)
986                   {
987                     /* Now that P->fts_statp is guaranteed to be valid,
988                        if this is a command-line directory, record its
989                        device number, to be used for FTS_XDEV.  */
990                     if (p->fts_level == FTS_ROOTLEVEL)
991                       sp->fts_dev = p->fts_statp->st_dev;
992                     Dprintf (("  entering: %s\n", p->fts_path));
993                     if (! enter_dir (sp, p))
994                       {
995                         __set_errno (ENOMEM);
996                         return NULL;
997                       }
998                   }
999                 return p;
1000         }
1001
1002         /* Move up to the parent node. */
1003         p = tmp->fts_parent;
1004         sp->fts_cur = p;
1005         free(tmp);
1006
1007         if (p->fts_level == FTS_ROOTPARENTLEVEL) {
1008                 /*
1009                  * Done; free everything up and set errno to 0 so the user
1010                  * can distinguish between error and EOF.
1011                  */
1012                 free(p);
1013                 __set_errno (0);
1014                 return (sp->fts_cur = NULL);
1015         }
1016
1017         fts_assert (p->fts_info != FTS_NSOK);
1018
1019         /* NUL terminate the file name.  */
1020         sp->fts_path[p->fts_pathlen] = '\0';
1021
1022         /*
1023          * Return to the parent directory.  If at a root node, restore
1024          * the initial working directory.  If we came through a symlink,
1025          * go back through the file descriptor.  Otherwise, move up
1026          * one level, via "..".
1027          */
1028         if (p->fts_level == FTS_ROOTLEVEL) {
1029                 if (RESTORE_INITIAL_CWD(sp)) {
1030                         p->fts_errno = errno;
1031                         SET(FTS_STOP);
1032                 }
1033         } else if (p->fts_flags & FTS_SYMFOLLOW) {
1034                 if (FCHDIR(sp, p->fts_symfd)) {
1035                         int saved_errno = errno;
1036                         (void)close(p->fts_symfd);
1037                         __set_errno (saved_errno);
1038                         p->fts_errno = errno;
1039                         SET(FTS_STOP);
1040                 }
1041                 (void)close(p->fts_symfd);
1042         } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
1043                    fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
1044                 p->fts_errno = errno;
1045                 SET(FTS_STOP);
1046         }
1047         p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
1048         if (p->fts_errno == 0)
1049                 LEAVE_DIR (sp, p, "3");
1050         return ISSET(FTS_STOP) ? NULL : p;
1051 }
1052
1053 /*
1054  * Fts_set takes the stream as an argument although it's not used in this
1055  * implementation; it would be necessary if anyone wanted to add global
1056  * semantics to fts using fts_set.  An error return is allowed for similar
1057  * reasons.
1058  */
1059 /* ARGSUSED */
1060 int
1061 fts_set(FTS *sp ATTRIBUTE_UNUSED, FTSENT *p, int instr)
1062 {
1063         if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
1064             instr != FTS_NOINSTR && instr != FTS_SKIP) {
1065                 __set_errno (EINVAL);
1066                 return (1);
1067         }
1068         p->fts_instr = instr;
1069         return (0);
1070 }
1071
1072 FTSENT *
1073 fts_children (register FTS *sp, int instr)
1074 {
1075         register FTSENT *p;
1076         int fd;
1077
1078         if (instr != 0 && instr != FTS_NAMEONLY) {
1079                 __set_errno (EINVAL);
1080                 return (NULL);
1081         }
1082
1083         /* Set current node pointer. */
1084         p = sp->fts_cur;
1085
1086         /*
1087          * Errno set to 0 so user can distinguish empty directory from
1088          * an error.
1089          */
1090         __set_errno (0);
1091
1092         /* Fatal errors stop here. */
1093         if (ISSET(FTS_STOP))
1094                 return (NULL);
1095
1096         /* Return logical hierarchy of user's arguments. */
1097         if (p->fts_info == FTS_INIT)
1098                 return (p->fts_link);
1099
1100         /*
1101          * If not a directory being visited in pre-order, stop here.  Could
1102          * allow FTS_DNR, assuming the user has fixed the problem, but the
1103          * same effect is available with FTS_AGAIN.
1104          */
1105         if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
1106                 return (NULL);
1107
1108         /* Free up any previous child list. */
1109         if (sp->fts_child != NULL)
1110                 fts_lfree(sp->fts_child);
1111
1112         if (instr == FTS_NAMEONLY) {
1113                 SET(FTS_NAMEONLY);
1114                 instr = BNAMES;
1115         } else
1116                 instr = BCHILD;
1117
1118         /*
1119          * If using chdir on a relative file name and called BEFORE fts_read
1120          * does its chdir to the root of a traversal, we can lose -- we need to
1121          * chdir into the subdirectory, and we don't know where the current
1122          * directory is, so we can't get back so that the upcoming chdir by
1123          * fts_read will work.
1124          */
1125         if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
1126             ISSET(FTS_NOCHDIR))
1127                 return (sp->fts_child = fts_build(sp, instr));
1128
1129         if ((fd = diropen (sp, ".")) < 0)
1130                 return (sp->fts_child = NULL);
1131         sp->fts_child = fts_build(sp, instr);
1132         if (ISSET(FTS_CWDFD))
1133           {
1134             cwd_advance_fd (sp, fd, true);
1135           }
1136         else
1137           {
1138             if (fchdir(fd))
1139               {
1140                 int saved_errno = errno;
1141                 close (fd);
1142                 __set_errno (saved_errno);
1143                 return NULL;
1144               }
1145             close (fd);
1146           }
1147         return (sp->fts_child);
1148 }
1149
1150 /* A comparison function to sort on increasing inode number.
1151    For some file system types, sorting either way makes a huge
1152    performance difference for a directory with very many entries,
1153    but sorting on increasing values is slightly better than sorting
1154    on decreasing values.  The difference is in the 5% range.  */
1155 static int
1156 fts_compare_ino (struct _ftsent const **a, struct _ftsent const **b)
1157 {
1158   return (a[0]->fts_statp->st_ino < b[0]->fts_statp->st_ino ? -1
1159           : b[0]->fts_statp->st_ino < a[0]->fts_statp->st_ino ? 1 : 0);
1160 }
1161
1162 /* Map the dirent.d_type value, DTYPE, to the corresponding stat.st_mode
1163    S_IF* bit and set ST.st_mode, thus clearing all other bits in that field.  */
1164 static void
1165 set_stat_type (struct stat *st, unsigned int dtype)
1166 {
1167   mode_t type;
1168   switch (dtype)
1169     {
1170     case DT_BLK:
1171       type = S_IFBLK;
1172       break;
1173     case DT_CHR:
1174       type = S_IFCHR;
1175       break;
1176     case DT_DIR:
1177       type = S_IFDIR;
1178       break;
1179     case DT_FIFO:
1180       type = S_IFIFO;
1181       break;
1182     case DT_LNK:
1183       type = S_IFLNK;
1184       break;
1185     case DT_REG:
1186       type = S_IFREG;
1187       break;
1188     case DT_SOCK:
1189       type = S_IFSOCK;
1190       break;
1191     default:
1192       type = 0;
1193     }
1194   st->st_mode = type;
1195 }
1196
1197 /*
1198  * This is the tricky part -- do not casually change *anything* in here.  The
1199  * idea is to build the linked list of entries that are used by fts_children
1200  * and fts_read.  There are lots of special cases.
1201  *
1202  * The real slowdown in walking the tree is the stat calls.  If FTS_NOSTAT is
1203  * set and it's a physical walk (so that symbolic links can't be directories),
1204  * we can do things quickly.  First, if it's a 4.4BSD file system, the type
1205  * of the file is in the directory entry.  Otherwise, we assume that the number
1206  * of subdirectories in a node is equal to the number of links to the parent.
1207  * The former skips all stat calls.  The latter skips stat calls in any leaf
1208  * directories and for any files after the subdirectories in the directory have
1209  * been found, cutting the stat calls by about 2/3.
1210  */
1211 static FTSENT *
1212 internal_function
1213 fts_build (register FTS *sp, int type)
1214 {
1215         register struct dirent *dp;
1216         register FTSENT *p, *head;
1217         register size_t nitems;
1218         FTSENT *cur, *tail;
1219         DIR *dirp;
1220         void *oldaddr;
1221         int saved_errno;
1222         bool descend;
1223         bool doadjust;
1224         ptrdiff_t level;
1225         nlink_t nlinks;
1226         bool nostat;
1227         size_t len, maxlen, new_len;
1228         char *cp;
1229
1230         /* Set current node pointer. */
1231         cur = sp->fts_cur;
1232
1233         /*
1234          * Open the directory for reading.  If this fails, we're done.
1235          * If being called from fts_read, set the fts_info field.
1236          */
1237 #if defined FTS_WHITEOUT && 0
1238         if (ISSET(FTS_WHITEOUT))
1239                 oflag = DTF_NODUP|DTF_REWIND;
1240         else
1241                 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
1242 #else
1243 # define __opendir2(file, flag) \
1244         ( ! ISSET(FTS_NOCHDIR) && ISSET(FTS_CWDFD) \
1245           ? opendirat(sp->fts_cwd_fd, file)        \
1246           : opendir(file))
1247 #endif
1248        if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
1249                 if (type == BREAD) {
1250                         cur->fts_info = FTS_DNR;
1251                         cur->fts_errno = errno;
1252                 }
1253                 return (NULL);
1254         }
1255        /* Rather than calling fts_stat for each and every entry encountered
1256           in the readdir loop (below), stat each directory only right after
1257           opening it.  */
1258        if (cur->fts_info == FTS_NSOK)
1259          cur->fts_info = fts_stat(sp, cur, false);
1260
1261         /*
1262          * Nlinks is the number of possible entries of type directory in the
1263          * directory if we're cheating on stat calls, 0 if we're not doing
1264          * any stat calls at all, (nlink_t) -1 if we're statting everything.
1265          */
1266         if (type == BNAMES) {
1267                 nlinks = 0;
1268                 /* Be quiet about nostat, GCC. */
1269                 nostat = false;
1270         } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
1271                 nlinks = (cur->fts_statp->st_nlink
1272                           - (ISSET(FTS_SEEDOT) ? 0 : 2));
1273                 nostat = true;
1274         } else {
1275                 nlinks = -1;
1276                 nostat = false;
1277         }
1278
1279         /*
1280          * If we're going to need to stat anything or we want to descend
1281          * and stay in the directory, chdir.  If this fails we keep going,
1282          * but set a flag so we don't chdir after the post-order visit.
1283          * We won't be able to stat anything, but we can still return the
1284          * names themselves.  Note, that since fts_read won't be able to
1285          * chdir into the directory, it will have to return different file
1286          * names than before, i.e. "a/b" instead of "b".  Since the node
1287          * has already been visited in pre-order, have to wait until the
1288          * post-order visit to return the error.  There is a special case
1289          * here, if there was nothing to stat then it's not an error to
1290          * not be able to stat.  This is all fairly nasty.  If a program
1291          * needed sorted entries or stat information, they had better be
1292          * checking FTS_NS on the returned nodes.
1293          */
1294         if (nlinks || type == BREAD) {
1295                 int dir_fd = dirfd(dirp);
1296                 if (ISSET(FTS_CWDFD) && 0 <= dir_fd)
1297                   dir_fd = dup (dir_fd);
1298                 if (dir_fd < 0 || fts_safe_changedir(sp, cur, dir_fd, NULL)) {
1299                         if (nlinks && type == BREAD)
1300                                 cur->fts_errno = errno;
1301                         cur->fts_flags |= FTS_DONTCHDIR;
1302                         descend = false;
1303                         closedir(dirp);
1304                         if (ISSET(FTS_CWDFD) && 0 <= dir_fd)
1305                                 close (dir_fd);
1306                         dirp = NULL;
1307                 } else
1308                         descend = true;
1309         } else
1310                 descend = false;
1311
1312         /*
1313          * Figure out the max file name length that can be stored in the
1314          * current buffer -- the inner loop allocates more space as necessary.
1315          * We really wouldn't have to do the maxlen calculations here, we
1316          * could do them in fts_read before returning the name, but it's a
1317          * lot easier here since the length is part of the dirent structure.
1318          *
1319          * If not changing directories set a pointer so that can just append
1320          * each new component into the file name.
1321          */
1322         len = NAPPEND(cur);
1323         if (ISSET(FTS_NOCHDIR)) {
1324                 cp = sp->fts_path + len;
1325                 *cp++ = '/';
1326         } else {
1327                 /* GCC, you're too verbose. */
1328                 cp = NULL;
1329         }
1330         len++;
1331         maxlen = sp->fts_pathlen - len;
1332
1333         level = cur->fts_level + 1;
1334
1335         /* Read the directory, attaching each entry to the `link' pointer. */
1336         doadjust = false;
1337         for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
1338                 bool is_dir;
1339
1340                 if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
1341                         continue;
1342
1343                 if ((p = fts_alloc (sp, dp->d_name,
1344                                     _D_EXACT_NAMLEN (dp))) == NULL)
1345                         goto mem1;
1346                 if (_D_EXACT_NAMLEN (dp) >= maxlen) {
1347                         /* include space for NUL */
1348                         oldaddr = sp->fts_path;
1349                         if (! fts_palloc(sp, _D_EXACT_NAMLEN (dp) + len + 1)) {
1350                                 /*
1351                                  * No more memory.  Save
1352                                  * errno, free up the current structure and the
1353                                  * structures already allocated.
1354                                  */
1355 mem1:                           saved_errno = errno;
1356                                 free(p);
1357                                 fts_lfree(head);
1358                                 closedir(dirp);
1359                                 cur->fts_info = FTS_ERR;
1360                                 SET(FTS_STOP);
1361                                 __set_errno (saved_errno);
1362                                 return (NULL);
1363                         }
1364                         /* Did realloc() change the pointer? */
1365                         if (oldaddr != sp->fts_path) {
1366                                 doadjust = true;
1367                                 if (ISSET(FTS_NOCHDIR))
1368                                         cp = sp->fts_path + len;
1369                         }
1370                         maxlen = sp->fts_pathlen - len;
1371                 }
1372
1373                 new_len = len + _D_EXACT_NAMLEN (dp);
1374                 if (new_len < len) {
1375                         /*
1376                          * In the unlikely event that we would end up
1377                          * with a file name longer than SIZE_MAX, free up
1378                          * the current structure and the structures already
1379                          * allocated, then error out with ENAMETOOLONG.
1380                          */
1381                         free(p);
1382                         fts_lfree(head);
1383                         closedir(dirp);
1384                         cur->fts_info = FTS_ERR;
1385                         SET(FTS_STOP);
1386                         __set_errno (ENAMETOOLONG);
1387                         return (NULL);
1388                 }
1389                 p->fts_level = level;
1390                 p->fts_parent = sp->fts_cur;
1391                 p->fts_pathlen = new_len;
1392
1393 #if defined FTS_WHITEOUT && 0
1394                 if (dp->d_type == DT_WHT)
1395                         p->fts_flags |= FTS_ISW;
1396 #endif
1397                 /* Store dirent.d_ino, in case we need to sort
1398                    entries before processing them.  */
1399                 p->fts_statp->st_ino = D_INO (dp);
1400
1401                 /* Build a file name for fts_stat to stat. */
1402                 if (ISSET(FTS_NOCHDIR)) {
1403                         p->fts_accpath = p->fts_path;
1404                         memmove(cp, p->fts_name, p->fts_namelen + 1);
1405                 } else
1406                         p->fts_accpath = p->fts_name;
1407
1408                 if (sp->fts_compar == NULL || ISSET(FTS_DEFER_STAT)) {
1409                         /* Record what fts_read will have to do with this
1410                            entry. In many cases, it will simply fts_stat it,
1411                            but we can take advantage of any d_type information
1412                            to optimize away the unnecessary stat calls.  I.e.,
1413                            if FTS_NOSTAT is in effect and we're not following
1414                            symlinks (FTS_PHYSICAL) and d_type indicates this
1415                            is *not* a directory, then we won't have to stat it
1416                            at all.  If it *is* a directory, then (currently)
1417                            we stat it regardless, in order to get device and
1418                            inode numbers.  Some day we might optimize that
1419                            away, too, for directories where d_ino is known to
1420                            be valid.  */
1421                         bool skip_stat = (ISSET(FTS_PHYSICAL)
1422                                           && ISSET(FTS_NOSTAT)
1423                                           && DT_IS_KNOWN(dp)
1424                                           && ! DT_MUST_BE(dp, DT_DIR));
1425                         p->fts_info = FTS_NSOK;
1426                         /* Propagate dirent.d_type information back
1427                            to caller, when possible.  */
1428                         set_stat_type (p->fts_statp, D_TYPE (dp));
1429                         fts_set_stat_required(p, !skip_stat);
1430                         is_dir = (ISSET(FTS_PHYSICAL)
1431                                   && DT_MUST_BE(dp, DT_DIR));
1432                 } else {
1433                         p->fts_info = fts_stat(sp, p, false);
1434                         is_dir = (p->fts_info == FTS_D
1435                                   || p->fts_info == FTS_DC
1436                                   || p->fts_info == FTS_DOT);
1437                 }
1438
1439                 /* Decrement link count if applicable. */
1440                 if (nlinks > 0 && is_dir)
1441                         nlinks -= nostat;
1442
1443                 /* We walk in directory order so "ls -f" doesn't get upset. */
1444                 p->fts_link = NULL;
1445                 if (head == NULL)
1446                         head = tail = p;
1447                 else {
1448                         tail->fts_link = p;
1449                         tail = p;
1450                 }
1451                 ++nitems;
1452         }
1453         if (dirp)
1454                 closedir(dirp);
1455
1456         /*
1457          * If realloc() changed the address of the file name, adjust the
1458          * addresses for the rest of the tree and the dir list.
1459          */
1460         if (doadjust)
1461                 fts_padjust(sp, head);
1462
1463         /*
1464          * If not changing directories, reset the file name back to original
1465          * state.
1466          */
1467         if (ISSET(FTS_NOCHDIR)) {
1468                 if (len == sp->fts_pathlen || nitems == 0)
1469                         --cp;
1470                 *cp = '\0';
1471         }
1472
1473         /*
1474          * If descended after called from fts_children or after called from
1475          * fts_read and nothing found, get back.  At the root level we use
1476          * the saved fd; if one of fts_open()'s arguments is a relative name
1477          * to an empty directory, we wind up here with no other way back.  If
1478          * can't get back, we're done.
1479          */
1480         if (descend && (type == BCHILD || !nitems) &&
1481             (cur->fts_level == FTS_ROOTLEVEL
1482              ? RESTORE_INITIAL_CWD(sp)
1483              : fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
1484                 cur->fts_info = FTS_ERR;
1485                 SET(FTS_STOP);
1486                 fts_lfree(head);
1487                 return (NULL);
1488         }
1489
1490         /* If didn't find anything, return NULL. */
1491         if (!nitems) {
1492                 if (type == BREAD)
1493                         cur->fts_info = FTS_DP;
1494                 fts_lfree(head);
1495                 return (NULL);
1496         }
1497
1498         /* If there are many entries, no sorting function has been specified,
1499            and this file system is of a type that may be slow with a large
1500            number of entries, then sort the directory entries on increasing
1501            inode numbers.  */
1502         if (nitems > _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
1503             && !sp->fts_compar
1504             && ISSET (FTS_CWDFD)
1505             && dirent_inode_sort_may_be_useful (sp->fts_cwd_fd)) {
1506                 sp->fts_compar = fts_compare_ino;
1507                 head = fts_sort (sp, head, nitems);
1508                 sp->fts_compar = NULL;
1509         }
1510
1511         /* Sort the entries. */
1512         if (sp->fts_compar && nitems > 1)
1513                 head = fts_sort(sp, head, nitems);
1514         return (head);
1515 }
1516
1517 #if FTS_DEBUG
1518
1519 /* Walk ->fts_parent links starting at E_CURR, until the root of the
1520    current hierarchy.  There should be a directory with dev/inode
1521    matching those of AD.  If not, print a lot of diagnostics.  */
1522 static void
1523 find_matching_ancestor (FTSENT const *e_curr, struct Active_dir const *ad)
1524 {
1525   FTSENT const *ent;
1526   for (ent = e_curr; ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1527     {
1528       if (ad->ino == ent->fts_statp->st_ino
1529           && ad->dev == ent->fts_statp->st_dev)
1530         return;
1531     }
1532   printf ("ERROR: tree dir, %s, not active\n", ad->fts_ent->fts_accpath);
1533   printf ("active dirs:\n");
1534   for (ent = e_curr;
1535        ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1536     printf ("  %s(%"PRIuMAX"/%"PRIuMAX") to %s(%"PRIuMAX"/%"PRIuMAX")...\n",
1537             ad->fts_ent->fts_accpath,
1538             (uintmax_t) ad->dev,
1539             (uintmax_t) ad->ino,
1540             ent->fts_accpath,
1541             (uintmax_t) ent->fts_statp->st_dev,
1542             (uintmax_t) ent->fts_statp->st_ino);
1543 }
1544
1545 void
1546 fts_cross_check (FTS const *sp)
1547 {
1548   FTSENT const *ent = sp->fts_cur;
1549   FTSENT const *t;
1550   if ( ! ISSET (FTS_TIGHT_CYCLE_CHECK))
1551     return;
1552
1553   Dprintf (("fts-cross-check cur=%s\n", ent->fts_path));
1554   /* Make sure every parent dir is in the tree.  */
1555   for (t = ent->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1556     {
1557       struct Active_dir ad;
1558       ad.ino = t->fts_statp->st_ino;
1559       ad.dev = t->fts_statp->st_dev;
1560       if ( ! hash_lookup (sp->fts_cycle.ht, &ad))
1561         printf ("ERROR: active dir, %s, not in tree\n", t->fts_path);
1562     }
1563
1564   /* Make sure every dir in the tree is an active dir.
1565      But ENT is not necessarily a directory.  If so, just skip this part. */
1566   if (ent->fts_parent->fts_level >= FTS_ROOTLEVEL
1567       && (ent->fts_info == FTS_DP
1568           || ent->fts_info == FTS_D))
1569     {
1570       struct Active_dir *ad;
1571       for (ad = hash_get_first (sp->fts_cycle.ht); ad != NULL;
1572            ad = hash_get_next (sp->fts_cycle.ht, ad))
1573         {
1574           find_matching_ancestor (ent, ad);
1575         }
1576     }
1577 }
1578
1579 static bool
1580 same_fd (int fd1, int fd2)
1581 {
1582   struct stat sb1, sb2;
1583   return (fstat (fd1, &sb1) == 0
1584           && fstat (fd2, &sb2) == 0
1585           && SAME_INODE (sb1, sb2));
1586 }
1587
1588 static void
1589 fd_ring_print (FTS const *sp, FILE *stream, char const *msg)
1590 {
1591   I_ring const *fd_ring = &sp->fts_fd_ring;
1592   unsigned int i = fd_ring->fts_front;
1593   char *cwd = getcwdat (sp->fts_cwd_fd, NULL, 0);
1594   fprintf (stream, "=== %s ========== %s\n", msg, cwd);
1595   free (cwd);
1596   if (i_ring_empty (fd_ring))
1597     return;
1598
1599   while (true)
1600     {
1601       int fd = fd_ring->fts_fd_ring[i];
1602       if (fd < 0)
1603         fprintf (stream, "%d: %d:\n", i, fd);
1604       else
1605         {
1606           char *wd = getcwdat (fd, NULL, 0);
1607           fprintf (stream, "%d: %d: %s\n", i, fd, wd);
1608           free (wd);
1609         }
1610       if (i == fd_ring->fts_back)
1611         break;
1612       i = (i + I_RING_SIZE - 1) % I_RING_SIZE;
1613     }
1614 }
1615
1616 /* Ensure that each file descriptor on the fd_ring matches a
1617    parent, grandparent, etc. of the current working directory.  */
1618 static void
1619 fd_ring_check (FTS const *sp)
1620 {
1621   if (!fts_debug)
1622     return;
1623
1624   /* Make a writable copy.  */
1625   I_ring fd_w = sp->fts_fd_ring;
1626
1627   int cwd_fd = sp->fts_cwd_fd;
1628   cwd_fd = dup (cwd_fd);
1629   char *dot = getcwdat (cwd_fd, NULL, 0);
1630   error (0, 0, "===== check ===== cwd: %s", dot);
1631   free (dot);
1632   while ( ! i_ring_empty (&fd_w))
1633     {
1634       int fd = i_ring_pop (&fd_w);
1635       if (0 <= fd)
1636         {
1637           int parent_fd = openat (cwd_fd, "..", O_RDONLY);
1638           if (parent_fd < 0)
1639             {
1640               // Warn?
1641               break;
1642             }
1643           if (!same_fd (fd, parent_fd))
1644             {
1645               char *cwd = getcwdat (fd, NULL, 0);
1646               error (0, errno, "ring  : %s", cwd);
1647               char *c2 = getcwdat (parent_fd, NULL, 0);
1648               error (0, errno, "parent: %s", c2);
1649               free (cwd);
1650               free (c2);
1651               fts_assert (0);
1652             }
1653           close (cwd_fd);
1654           cwd_fd = parent_fd;
1655         }
1656     }
1657   close (cwd_fd);
1658 }
1659 #endif
1660
1661 static unsigned short int
1662 internal_function
1663 fts_stat(FTS *sp, register FTSENT *p, bool follow)
1664 {
1665         struct stat *sbp = p->fts_statp;
1666         int saved_errno;
1667
1668         if (p->fts_level == FTS_ROOTLEVEL && ISSET(FTS_COMFOLLOW))
1669                 follow = true;
1670
1671 #if defined FTS_WHITEOUT && 0
1672         /* check for whiteout */
1673         if (p->fts_flags & FTS_ISW) {
1674                 memset(sbp, '\0', sizeof (*sbp));
1675                 sbp->st_mode = S_IFWHT;
1676                 return (FTS_W);
1677        }
1678 #endif
1679
1680         /*
1681          * If doing a logical walk, or application requested FTS_FOLLOW, do
1682          * a stat(2).  If that fails, check for a non-existent symlink.  If
1683          * fail, set the errno from the stat call.
1684          */
1685         if (ISSET(FTS_LOGICAL) || follow) {
1686                 if (stat(p->fts_accpath, sbp)) {
1687                         saved_errno = errno;
1688                         if (errno == ENOENT
1689                             && lstat(p->fts_accpath, sbp) == 0) {
1690                                 __set_errno (0);
1691                                 return (FTS_SLNONE);
1692                         }
1693                         p->fts_errno = saved_errno;
1694                         goto err;
1695                 }
1696         } else if (fstatat(sp->fts_cwd_fd, p->fts_accpath, sbp,
1697                            AT_SYMLINK_NOFOLLOW)) {
1698                 p->fts_errno = errno;
1699 err:            memset(sbp, 0, sizeof(struct stat));
1700                 return (FTS_NS);
1701         }
1702
1703         if (S_ISDIR(sbp->st_mode)) {
1704                 p->fts_n_dirs_remaining = (sbp->st_nlink
1705                                            - (ISSET(FTS_SEEDOT) ? 0 : 2));
1706                 if (ISDOT(p->fts_name)) {
1707                         /* Command-line "." and ".." are real directories. */
1708                         return (p->fts_level == FTS_ROOTLEVEL ? FTS_D : FTS_DOT);
1709                 }
1710
1711 #if !GNULIB_FTS
1712                 {
1713                   /*
1714                    * Cycle detection is done by brute force when the directory
1715                    * is first encountered.  If the tree gets deep enough or the
1716                    * number of symbolic links to directories is high enough,
1717                    * something faster might be worthwhile.
1718                    */
1719                   FTSENT *t;
1720
1721                   for (t = p->fts_parent;
1722                        t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1723                     if (sbp->st_ino == t->fts_statp->st_ino
1724                         && sbp->st_dev == t->fts_statp->st_dev)
1725                       {
1726                         p->fts_cycle = t;
1727                         return (FTS_DC);
1728                       }
1729                 }
1730 #endif
1731
1732                 return (FTS_D);
1733         }
1734         if (S_ISLNK(sbp->st_mode))
1735                 return (FTS_SL);
1736         if (S_ISREG(sbp->st_mode))
1737                 return (FTS_F);
1738         return (FTS_DEFAULT);
1739 }
1740
1741 static int
1742 fts_compar (void const *a, void const *b)
1743 {
1744   /* Convert A and B to the correct types, to pacify the compiler, and
1745      for portability to bizarre hosts where "void const *" and "FTSENT
1746      const **" differ in runtime representation.  The comparison
1747      function cannot modify *a and *b, but there is no compile-time
1748      check for this.  */
1749   FTSENT const **pa = (FTSENT const **) a;
1750   FTSENT const **pb = (FTSENT const **) b;
1751   return pa[0]->fts_fts->fts_compar (pa, pb);
1752 }
1753
1754 static FTSENT *
1755 internal_function
1756 fts_sort (FTS *sp, FTSENT *head, register size_t nitems)
1757 {
1758         register FTSENT **ap, *p;
1759
1760         /* On most modern hosts, void * and FTSENT ** have the same
1761            run-time representation, and one can convert sp->fts_compar to
1762            the type qsort expects without problem.  Use the heuristic that
1763            this is OK if the two pointer types are the same size, and if
1764            converting FTSENT ** to long int is the same as converting
1765            FTSENT ** to void * and then to long int.  This heuristic isn't
1766            valid in general but we don't know of any counterexamples.  */
1767         FTSENT *dummy;
1768         int (*compare) (void const *, void const *) =
1769           ((sizeof &dummy == sizeof (void *)
1770             && (long int) &dummy == (long int) (void *) &dummy)
1771            ? (int (*) (void const *, void const *)) sp->fts_compar
1772            : fts_compar);
1773
1774         /*
1775          * Construct an array of pointers to the structures and call qsort(3).
1776          * Reassemble the array in the order returned by qsort.  If unable to
1777          * sort for memory reasons, return the directory entries in their
1778          * current order.  Allocate enough space for the current needs plus
1779          * 40 so don't realloc one entry at a time.
1780          */
1781         if (nitems > sp->fts_nitems) {
1782                 FTSENT **a;
1783
1784                 sp->fts_nitems = nitems + 40;
1785                 if (SIZE_MAX / sizeof *a < sp->fts_nitems
1786                     || ! (a = realloc (sp->fts_array,
1787                                        sp->fts_nitems * sizeof *a))) {
1788                         free(sp->fts_array);
1789                         sp->fts_array = NULL;
1790                         sp->fts_nitems = 0;
1791                         return (head);
1792                 }
1793                 sp->fts_array = a;
1794         }
1795         for (ap = sp->fts_array, p = head; p; p = p->fts_link)
1796                 *ap++ = p;
1797         qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), compare);
1798         for (head = *(ap = sp->fts_array); --nitems; ++ap)
1799                 ap[0]->fts_link = ap[1];
1800         ap[0]->fts_link = NULL;
1801         return (head);
1802 }
1803
1804 static FTSENT *
1805 internal_function
1806 fts_alloc (FTS *sp, const char *name, register size_t namelen)
1807 {
1808         register FTSENT *p;
1809         size_t len;
1810
1811         /*
1812          * The file name is a variable length array.  Allocate the FTSENT
1813          * structure and the file name in one chunk.
1814          */
1815         len = sizeof(FTSENT) + namelen;
1816         if ((p = malloc(len)) == NULL)
1817                 return (NULL);
1818
1819         /* Copy the name and guarantee NUL termination. */
1820         memmove(p->fts_name, name, namelen);
1821         p->fts_name[namelen] = '\0';
1822
1823         p->fts_namelen = namelen;
1824         p->fts_fts = sp;
1825         p->fts_path = sp->fts_path;
1826         p->fts_errno = 0;
1827         p->fts_flags = 0;
1828         p->fts_instr = FTS_NOINSTR;
1829         p->fts_number = 0;
1830         p->fts_pointer = NULL;
1831         return (p);
1832 }
1833
1834 static void
1835 internal_function
1836 fts_lfree (register FTSENT *head)
1837 {
1838         register FTSENT *p;
1839
1840         /* Free a linked list of structures. */
1841         while ((p = head)) {
1842                 head = head->fts_link;
1843                 free(p);
1844         }
1845 }
1846
1847 /*
1848  * Allow essentially unlimited file name lengths; find, rm, ls should
1849  * all work on any tree.  Most systems will allow creation of file
1850  * names much longer than MAXPATHLEN, even though the kernel won't
1851  * resolve them.  Add the size (not just what's needed) plus 256 bytes
1852  * so don't realloc the file name 2 bytes at a time.
1853  */
1854 static bool
1855 internal_function
1856 fts_palloc (FTS *sp, size_t more)
1857 {
1858         char *p;
1859         size_t new_len = sp->fts_pathlen + more + 256;
1860
1861         /*
1862          * See if fts_pathlen would overflow.
1863          */
1864         if (new_len < sp->fts_pathlen) {
1865                 free(sp->fts_path);
1866                 sp->fts_path = NULL;
1867                 __set_errno (ENAMETOOLONG);
1868                 return false;
1869         }
1870         sp->fts_pathlen = new_len;
1871         p = realloc(sp->fts_path, sp->fts_pathlen);
1872         if (p == NULL) {
1873                 free(sp->fts_path);
1874                 sp->fts_path = NULL;
1875                 return false;
1876         }
1877         sp->fts_path = p;
1878         return true;
1879 }
1880
1881 /*
1882  * When the file name is realloc'd, have to fix all of the pointers in
1883  *  structures already returned.
1884  */
1885 static void
1886 internal_function
1887 fts_padjust (FTS *sp, FTSENT *head)
1888 {
1889         FTSENT *p;
1890         char *addr = sp->fts_path;
1891
1892 #define ADJUST(p) do {                                                  \
1893         if ((p)->fts_accpath != (p)->fts_name) {                        \
1894                 (p)->fts_accpath =                                      \
1895                     (char *)addr + ((p)->fts_accpath - (p)->fts_path);  \
1896         }                                                               \
1897         (p)->fts_path = addr;                                           \
1898 } while (0)
1899         /* Adjust the current set of children. */
1900         for (p = sp->fts_child; p; p = p->fts_link)
1901                 ADJUST(p);
1902
1903         /* Adjust the rest of the tree, including the current level. */
1904         for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
1905                 ADJUST(p);
1906                 p = p->fts_link ? p->fts_link : p->fts_parent;
1907         }
1908 }
1909
1910 static size_t
1911 internal_function
1912 fts_maxarglen (char * const *argv)
1913 {
1914         size_t len, max;
1915
1916         for (max = 0; *argv; ++argv)
1917                 if ((len = strlen(*argv)) > max)
1918                         max = len;
1919         return (max + 1);
1920 }
1921
1922 /*
1923  * Change to dir specified by fd or file name without getting
1924  * tricked by someone changing the world out from underneath us.
1925  * Assumes p->fts_statp->st_dev and p->fts_statp->st_ino are filled in.
1926  * If FD is non-negative, expect it to be used after this function returns,
1927  * and to be closed eventually.  So don't pass e.g., `dirfd(dirp)' and then
1928  * do closedir(dirp), because that would invalidate the saved FD.
1929  * Upon failure, close FD immediately and return nonzero.
1930  */
1931 static int
1932 internal_function
1933 fts_safe_changedir (FTS *sp, FTSENT *p, int fd, char const *dir)
1934 {
1935         int ret;
1936         bool is_dotdot = dir && STREQ (dir, "..");
1937         int newfd;
1938
1939         /* This clause handles the unusual case in which FTS_NOCHDIR
1940            is specified, along with FTS_CWDFD.  In that case, there is
1941            no need to change even the virtual cwd file descriptor.
1942            However, if FD is non-negative, we do close it here.  */
1943         if (ISSET (FTS_NOCHDIR))
1944           {
1945             if (ISSET (FTS_CWDFD) && 0 <= fd)
1946               close (fd);
1947             return 0;
1948           }
1949
1950         if (fd < 0 && is_dotdot && ISSET (FTS_CWDFD))
1951           {
1952             /* When possible, skip the diropen and subsequent fstat+dev/ino
1953                comparison.  I.e., when changing to parent directory
1954                (chdir ("..")), use a file descriptor from the ring and
1955                save the overhead of diropen+fstat, as well as avoiding
1956                failure when we lack "x" access to the virtual cwd.  */
1957             if ( ! i_ring_empty (&sp->fts_fd_ring))
1958               {
1959                 int parent_fd;
1960                 fd_ring_print (sp, stderr, "pre-pop");
1961                 parent_fd = i_ring_pop (&sp->fts_fd_ring);
1962                 is_dotdot = true;
1963                 if (0 <= parent_fd)
1964                   {
1965                     fd = parent_fd;
1966                     dir = NULL;
1967                   }
1968               }
1969           }
1970
1971         newfd = fd;
1972         if (fd < 0 && (newfd = diropen (sp, dir)) < 0)
1973           return -1;
1974
1975         /* The following dev/inode check is necessary if we're doing a
1976            `logical' traversal (through symlinks, a la chown -L), if the
1977            system lacks O_NOFOLLOW support, or if we're changing to ".."
1978            (but not via a popped file descriptor).  When changing to the
1979            name "..", O_NOFOLLOW can't help.  In general, when the target is
1980            not "..", diropen's use of O_NOFOLLOW ensures we don't mistakenly
1981            follow a symlink, so we can avoid the expense of this fstat.  */
1982         if (ISSET(FTS_LOGICAL) || ! HAVE_WORKING_O_NOFOLLOW
1983             || (dir && STREQ (dir, "..")))
1984           {
1985             struct stat sb;
1986             if (fstat(newfd, &sb))
1987               {
1988                 ret = -1;
1989                 goto bail;
1990               }
1991             if (p->fts_statp->st_dev != sb.st_dev
1992                 || p->fts_statp->st_ino != sb.st_ino)
1993               {
1994                 __set_errno (ENOENT);           /* disinformation */
1995                 ret = -1;
1996                 goto bail;
1997               }
1998           }
1999
2000         if (ISSET(FTS_CWDFD))
2001           {
2002             cwd_advance_fd (sp, newfd, ! is_dotdot);
2003             return 0;
2004           }
2005
2006         ret = fchdir(newfd);
2007 bail:
2008         if (fd < 0)
2009           {
2010             int oerrno = errno;
2011             (void)close(newfd);
2012             __set_errno (oerrno);
2013           }
2014         return ret;
2015 }