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