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