1ftw(3) Library Functions Manual ftw(3)
2
3
4
6 ftw, nftw - file tree walk
7
9 Standard C library (libc, -lc)
10
12 #include <ftw.h>
13
14 int nftw(const char *dirpath,
15 int (*fn)(const char *fpath, const struct stat *sb,
16 int typeflag, struct FTW *ftwbuf),
17 int nopenfd, int flags);
18
19 [[deprecated]]
20 int ftw(const char *dirpath,
21 int (*fn)(const char *fpath, const struct stat *sb,
22 int typeflag),
23 int nopenfd);
24
25 Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
26
27 nftw():
28 _XOPEN_SOURCE >= 500
29
31 nftw() walks through the directory tree that is located under the di‐
32 rectory dirpath, and calls fn() once for each entry in the tree. By
33 default, directories are handled before the files and subdirectories
34 they contain (preorder traversal).
35
36 To avoid using up all of the calling process's file descriptors,
37 nopenfd specifies the maximum number of directories that nftw() will
38 hold open simultaneously. When the search depth exceeds this, nftw()
39 will become slower because directories have to be closed and reopened.
40 nftw() uses at most one file descriptor for each level in the directory
41 tree.
42
43 For each entry found in the tree, nftw() calls fn() with four argu‐
44 ments: fpath, sb, typeflag, and ftwbuf. fpath is the pathname of the
45 entry, and is expressed either as a pathname relative to the calling
46 process's current working directory at the time of the call to nftw(),
47 if dirpath was expressed as a relative pathname, or as an absolute
48 pathname, if dirpath was expressed as an absolute pathname. sb is a
49 pointer to the stat structure returned by a call to stat(2) for fpath.
50
51 The typeflag argument passed to fn() is an integer that has one of the
52 following values:
53
54 FTW_F fpath is a regular file.
55
56 FTW_D fpath is a directory.
57
58 FTW_DNR
59 fpath is a directory which can't be read.
60
61 FTW_DP fpath is a directory, and FTW_DEPTH was specified in flags. (If
62 FTW_DEPTH was not specified in flags, then directories will al‐
63 ways be visited with typeflag set to FTW_D.) All of the files
64 and subdirectories within fpath have been processed.
65
66 FTW_NS The stat(2) call failed on fpath, which is not a symbolic link.
67 The probable cause for this is that the caller had read permis‐
68 sion on the parent directory, so that the filename fpath could
69 be seen, but did not have execute permission, so that the file
70 could not be reached for stat(2). The contents of the buffer
71 pointed to by sb are undefined.
72
73 FTW_SL fpath is a symbolic link, and FTW_PHYS was set in flags.
74
75 FTW_SLN
76 fpath is a symbolic link pointing to a nonexistent file. (This
77 occurs only if FTW_PHYS is not set.) In this case the sb argu‐
78 ment passed to fn() contains information returned by performing
79 lstat(2) on the "dangling" symbolic link. (But see BUGS.)
80
81 The fourth argument (ftwbuf) that nftw() supplies when calling fn() is
82 a pointer to a structure of type FTW:
83
84 struct FTW {
85 int base;
86 int level;
87 };
88
89 base is the offset of the filename (i.e., basename component) in the
90 pathname given in fpath. level is the depth of fpath in the directory
91 tree, relative to the root of the tree (dirpath, which has depth 0).
92
93 To stop the tree walk, fn() returns a nonzero value; this value will
94 become the return value of nftw(). As long as fn() returns 0, nftw()
95 will continue either until it has traversed the entire tree, in which
96 case it will return zero, or until it encounters an error (such as a
97 malloc(3) failure), in which case it will return -1.
98
99 Because nftw() uses dynamic data structures, the only safe way to exit
100 out of a tree walk is to return a nonzero value from fn(). To allow a
101 signal to terminate the walk without causing a memory leak, have the
102 handler set a global flag that is checked by fn(). Don't use
103 longjmp(3) unless the program is going to terminate.
104
105 The flags argument of nftw() is formed by ORing zero or more of the
106 following flags:
107
108 FTW_ACTIONRETVAL (since glibc 2.3.3)
109 If this glibc-specific flag is set, then nftw() handles the re‐
110 turn value from fn() differently. fn() should return one of the
111 following values:
112
113 FTW_CONTINUE
114 Instructs nftw() to continue normally.
115
116 FTW_SKIP_SIBLINGS
117 If fn() returns this value, then siblings of the current
118 entry will be skipped, and processing continues in the
119 parent.
120
121 FTW_SKIP_SUBTREE
122 If fn() is called with an entry that is a directory
123 (typeflag is FTW_D), this return value will prevent ob‐
124 jects within that directory from being passed as argu‐
125 ments to fn(). nftw() continues processing with the next
126 sibling of the directory.
127
128 FTW_STOP
129 Causes nftw() to return immediately with the return value
130 FTW_STOP.
131
132 Other return values could be associated with new actions in the
133 future; fn() should not return values other than those listed
134 above.
135
136 The feature test macro _GNU_SOURCE must be defined (before in‐
137 cluding any header files) in order to obtain the definition of
138 FTW_ACTIONRETVAL from <ftw.h>.
139
140 FTW_CHDIR
141 If set, do a chdir(2) to each directory before handling its con‐
142 tents. This is useful if the program needs to perform some ac‐
143 tion in the directory in which fpath resides. (Specifying this
144 flag has no effect on the pathname that is passed in the fpath
145 argument of fn.)
146
147 FTW_DEPTH
148 If set, do a post-order traversal, that is, call fn() for the
149 directory itself after handling the contents of the directory
150 and its subdirectories. (By default, each directory is handled
151 before its contents.)
152
153 FTW_MOUNT
154 If set, stay within the same filesystem (i.e., do not cross
155 mount points).
156
157 FTW_PHYS
158 If set, do not follow symbolic links. (This is what you want.)
159 If not set, symbolic links are followed, but no file is reported
160 twice.
161
162 If FTW_PHYS is not set, but FTW_DEPTH is set, then the function
163 fn() is never called for a directory that would be a descendant
164 of itself.
165
166 ftw()
167 ftw() is an older function that offers a subset of the functionality of
168 nftw(). The notable differences are as follows:
169
170 • ftw() has no flags argument. It behaves the same as when nftw() is
171 called with flags specified as zero.
172
173 • The callback function, fn(), is not supplied with a fourth argument.
174
175 • The range of values that is passed via the typeflag argument sup‐
176 plied to fn() is smaller: just FTW_F, FTW_D, FTW_DNR, FTW_NS, and
177 (possibly) FTW_SL.
178
180 These functions return 0 on success, and -1 if an error occurs.
181
182 If fn() returns nonzero, then the tree walk is terminated and the value
183 returned by fn() is returned as the result of ftw() or nftw().
184
185 If nftw() is called with the FTW_ACTIONRETVAL flag, then the only non‐
186 zero value that should be used by fn() to terminate the tree walk is
187 FTW_STOP, and that value is returned as the result of nftw().
188
190 For an explanation of the terms used in this section, see at‐
191 tributes(7).
192
193 ┌────────────────────────────────────────┬───────────────┬─────────────┐
194 │Interface │ Attribute │ Value │
195 ├────────────────────────────────────────┼───────────────┼─────────────┤
196 │nftw() │ Thread safety │ MT-Safe cwd │
197 ├────────────────────────────────────────┼───────────────┼─────────────┤
198 │ftw() │ Thread safety │ MT-Safe │
199 └────────────────────────────────────────┴───────────────┴─────────────┘
200
202 In some implementations (e.g., glibc), ftw() will never use FTW_SL; on
203 other systems FTW_SL occurs only for symbolic links that do not point
204 to an existing file; and again on other systems ftw() will use FTW_SL
205 for each symbolic link. If fpath is a symbolic link and stat(2)
206 failed, POSIX.1-2008 states that it is undefined whether FTW_NS or
207 FTW_SL is passed in typeflag. For predictable results, use nftw().
208
210 POSIX.1-2008.
211
213 ftw() POSIX.1-2001, SVr4, SUSv1. POSIX.1-2008 marks it as obsolete.
214
215 nftw() glibc 2.1. POSIX.1-2001, SUSv1.
216
217 FTW_SL POSIX.1-2001, SUSv1.
218
220 POSIX.1-2008 notes that the results are unspecified if fn does not pre‐
221 serve the current working directory.
222
224 According to POSIX.1-2008, when the typeflag argument passed to fn()
225 contains FTW_SLN, the buffer pointed to by sb should contain informa‐
226 tion about the dangling symbolic link (obtained by calling lstat(2) on
227 the link). Early glibc versions correctly followed the POSIX specifi‐
228 cation on this point. However, as a result of a regression introduced
229 in glibc 2.4, the contents of the buffer pointed to by sb were unde‐
230 fined when FTW_SLN is passed in typeflag. (More precisely, the con‐
231 tents of the buffer were left unchanged in this case.) This regression
232 was eventually fixed in glibc 2.30, so that the glibc implementation
233 (once more) follows the POSIX specification.
234
236 The following program traverses the directory tree under the path named
237 in its first command-line argument, or under the current directory if
238 no argument is supplied. It displays various information about each
239 file. The second command-line argument can be used to specify charac‐
240 ters that control the value assigned to the flags argument when calling
241 nftw().
242
243 Program source
244
245 #define _XOPEN_SOURCE 500
246 #include <ftw.h>
247 #include <stdint.h>
248 #include <stdio.h>
249 #include <stdlib.h>
250 #include <string.h>
251
252 static int
253 display_info(const char *fpath, const struct stat *sb,
254 int tflag, struct FTW *ftwbuf)
255 {
256 printf("%-3s %2d ",
257 (tflag == FTW_D) ? "d" : (tflag == FTW_DNR) ? "dnr" :
258 (tflag == FTW_DP) ? "dp" : (tflag == FTW_F) ? "f" :
259 (tflag == FTW_NS) ? "ns" : (tflag == FTW_SL) ? "sl" :
260 (tflag == FTW_SLN) ? "sln" : "???",
261 ftwbuf->level);
262
263 if (tflag == FTW_NS)
264 printf("-------");
265 else
266 printf("%7jd", (intmax_t) sb->st_size);
267
268 printf(" %-40s %d %s\n",
269 fpath, ftwbuf->base, fpath + ftwbuf->base);
270
271 return 0; /* To tell nftw() to continue */
272 }
273
274 int
275 main(int argc, char *argv[])
276 {
277 int flags = 0;
278
279 if (argc > 2 && strchr(argv[2], 'd') != NULL)
280 flags |= FTW_DEPTH;
281 if (argc > 2 && strchr(argv[2], 'p') != NULL)
282 flags |= FTW_PHYS;
283
284 if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags)
285 == -1)
286 {
287 perror("nftw");
288 exit(EXIT_FAILURE);
289 }
290
291 exit(EXIT_SUCCESS);
292 }
293
295 stat(2), fts(3), readdir(3)
296
297
298
299Linux man-pages 6.04 2023-03-30 ftw(3)