annotate lib/fts.c @ 12378:ec1305e3ea1c

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