.\" Copyright (c) 1993 Michael Haardt (michael@moria.de)
.\" and copyright (c) 1999 Andries Brouwer (aeb@cwi.nl)
.\" and copyright (c) 2006 Justin Pryzby <justinpryzby@users.sf.net>
-.\" and copyright (c) 2006 Michael Kerrisk <mtk-manpages@gmx.net>
+.\" and copyright (c) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
.\"
+.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
.\" This is free documentation; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License as
.\" published by the Free Software Foundation; either version 2 of
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public
-.\" License along with this manual; if not, write to the Free
-.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
-.\" USA.
+.\" License along with this manual; if not, see
+.\" <http://www.gnu.org/licenses/>.
+.\" %%%LICENSE_END
.\"
.\" Modified Sun Jul 25 11:02:22 1993 by Rik Faith (faith@cs.unc.edu)
.\" 2006-05-24, Justin Pryzby <justinpryzby@users.sf.net>
-.\" document FTW_ACTIONRETVAL; include .SH "RETURN VALUE";
+.\" document FTW_ACTIONRETVAL; include .SH RETURN VALUE;
.\" 2006-05-24, Justin Pryzby <justinpryzby@users.sf.net> and
-.\" Michael Kerrisk <mtk-manpages@gmx.net>
+.\" Michael Kerrisk <mtk.manpages@gmail.com>
.\" reorganized and rewrote much of the page
-.\" 2006-05-24, Michael Kerrisk <mtk-manpages@gmx.net>
+.\" 2006-05-24, Michael Kerrisk <mtk.manpages@gmail.com>
.\" Added an example program.
-.TH FTW 3 2006-05-24 "Linux" "Linux Programmer's Manual"
+.\"
+.TH FTW 3 2019-03-06 "Linux" "Linux Programmer's Manual"
.SH NAME
ftw, nftw \- file tree walk
.SH SYNOPSIS
.nf
.B #include <ftw.h>
-.sp
-.BI "int ftw(const char *" dirpath ,
-.BR " int (*" fn ") (const char *" fpath ", const struct stat *" sb ,
-.BI " int " typeflag ),
-.BI " int " nopenfd );
-.sp
-.B #define _XOPEN_SOURCE 500
-.B #include <ftw.h>
-.sp
-.BI "int nftw(const char *" dirpath ,
-.BI " int (*" fn ") (const char *" fpath ", const struct stat *" sb ,
+.PP
+.BI "int nftw(const char *" dirpath ,
+.BI " int (*" fn ") (const char *" fpath ", const struct stat *" sb ,
.BI " int " typeflag ", struct FTW *" ftwbuf ),
.BI " int " nopenfd ", int " flags );
+.PP
+.B #include <ftw.h>
+.PP
+.BI "int ftw(const char *" dirpath ,
+.BI " int (*" fn ") (const char *" fpath ", const struct stat *" sb ,
+.BI " int " typeflag ),
+.BI " int " nopenfd );
.fi
+.PP
+.in -4n
+Feature Test Macro Requirements for glibc (see
+.BR feature_test_macros (7)):
+.in
+.PP
+.BR nftw ():
+_XOPEN_SOURCE >= 500
.SH DESCRIPTION
-\fBftw\fP() walks through the directory tree that is
+.BR nftw ()
+walks through the directory tree that is
located under the directory \fIdirpath\fP,
and calls \fIfn\fP() once for each entry in the tree.
-By default, directories are handled before the files and
-subdirectories they contain (pre-order traversal).
-
-To avoid using up all of the calling process's file descriptors,
-\fInopenfd\fP specifies the maximum number of directories that
-\fBftw\fP() will hold open simultaneously.
+By default, directories are handled before the files and
+subdirectories they contain (preorder traversal).
+.PP
+To avoid using up all of the calling process's file descriptors,
+\fInopenfd\fP specifies the maximum number of directories that
+.BR nftw ()
+will hold open simultaneously.
When
-the search depth exceeds this, \fBftw\fP() will become slower because
-directories have to be closed and reopened. \fBftw\fP() uses at most
+the search depth exceeds this,
+.BR nftw ()
+will become slower because
+directories have to be closed and reopened.
+.BR nftw ()
+uses at most
one file descriptor for each level in the directory tree.
-
-For each entry found in the tree,
-.BR ftw ()
+.PP
+For each entry found in the tree,
+.BR nftw ()
calls
-\fIfn\fP() with three arguments:
+\fIfn\fP() with four arguments:
.IR fpath ,
.IR sb ,
+.IR typeflag ,
and
-.IR typeflag .
-.IR fpath
-is the pathname of the entry relative to
-.IR dirpath .
-.IR sb
+.IR ftwbuf .
+.I fpath
+is the pathname of the entry,
+and is expressed either as a pathname relative to the calling process's
+current working directory at the time of the call to
+.BR nftw (),
+if
+.IR dirpath
+was expressed as a relative pathname,
+or as an absolute pathname, if
+.I dirpath
+was expressed as an absolute pathname.
+.I sb
is a pointer to the
-.IR stat
-structure returned by a call to
-.BR stat (2)
-for
+.I stat
+structure returned by a call to
+.BR stat (2)
+for
.IR fpath .
-.IR typeflag
+.PP
+The
+.I typeflag
+argument passed to
+.IR fn ()
is an integer that has one of the following values:
.TP
.B FTW_F
.I fpath
-is a normal file.
+is a regular file.
.TP
.B FTW_D
.I fpath
.I fpath
is a directory which can't be read.
.TP
+.B FTW_DP
+.I fpath
+is a directory, and \fBFTW_DEPTH\fP was specified in \fIflags\fP.
+(If
+.B FTW_DEPTH
+was not specified in
+.IR flags ,
+then directories will always be visited with
+.I typeflag
+set to
+.BR FTW_D .)
+All of the files
+and subdirectories within \fIfpath\fP have been processed.
+.TP
.B FTW_NS
-The
-.BR stat (2)
-call failed on
+The
+.BR stat (2)
+call failed on
.IR fpath ,
which is not a symbolic link.
-.sp
-If
+The probable cause for this is that the caller had read permission
+on the parent directory, so that the filename
.I fpath
-is a symbolic link and
-.BR stat (2)
-failed, POSIX.1-2001 states
-that it is undefined whether \fBFTW_NS\fP or \fBFTW_SL\fP (see below)
-is passed in
-.IR typeflag .
+could be seen,
+but did not have execute permission,
+so that the file could not be reached for
+.BR stat (2).
+The contents of the buffer pointed to by
+.I sb
+are undefined.
+.TP
+.B FTW_SL
+.I fpath
+is a symbolic link, and \fBFTW_PHYS\fP was set in \fIflags\fP.
+.\" To obtain the definition of this constant from
+.\" .IR <ftw.h> ,
+.\" either
+.\" .B _BSD_SOURCE
+.\" must be defined, or
+.\" .BR _XOPEN_SOURCE
+.\" must be defined with a value of 500 or more.
+.TP
+.B FTW_SLN
+.I fpath
+is a symbolic link pointing to a nonexistent file.
+(This occurs only if \fBFTW_PHYS\fP is not set.)
+On most implementations, in this case the
+.I sb
+argument passed to
+.IR fn ()
+contains information returned by performing
+.BR lstat (2)
+on the symbolic link.
+For the details on Linux, see BUGS.
+.PP
+The fourth argument
+.RI ( ftwbuf )
+that
+.BR nftw ()
+supplies when calling
+\fIfn\fP()
+is a pointer to a structure of type \fIFTW\fP:
.PP
-To stop the tree walk, \fIfn\fP() returns a non-zero value; this
-value will become the return value of \fBftw\fP().
+.in +4n
+.EX
+struct FTW {
+ int base;
+ int level;
+};
+.EE
+.in
+.PP
+.I base
+is the offset of the filename (i.e., basename component)
+in the pathname given in
+.IR fpath .
+.I level
+is the depth of
+.I fpath
+in the directory tree, relative to the root of the tree
+.RI ( dirpath ,
+which has depth 0).
+.PP
+To stop the tree walk, \fIfn\fP() returns a nonzero value; this
+value will become the return value of
+.BR nftw ().
As long as \fIfn\fP() returns 0,
-\fBftw\fP() will continue either until it has traversed the entire tree,
-in which case it will return zero,
+.BR nftw ()
+will continue either until it has traversed the entire tree,
+in which case it will return zero,
or until it encounters an error (such as a
.BR malloc (3)
failure), in which case it will return \-1.
.PP
-Because \fBftw\fP() uses dynamic data structures, the only safe way to
-exit out of a tree walk is to return a non-zero value from \fIfn\fP().
+Because
+.BR nftw ()
+uses dynamic data structures, the only safe way to
+exit out of a tree walk is to return a nonzero value from \fIfn\fP().
To allow a signal to terminate the walk without causing a memory leak,
have the handler set a global flag that is checked by \fIfn\fP().
-\fIDon't\fP use \fBlongjmp\fP(3) unless the program is going to terminate.
-.SS nftw()
-The function \fBnftw\fP() is the same as \fBftw\fP(),
-except that it has one additional argument, \fIflags\fP,
-and calls \fIfn\fP() with one more argument, \fIftwbuf\fP.
-
-This \fIflags\fP argument is formed by ORing zero or more of the
+\fIDon't\fP use
+.BR longjmp (3)
+unless the program is going to terminate.
+.PP
+The \fIflags\fP argument of
+.BR nftw ()
+is formed by ORing zero or more of the
following flags:
.TP
.BR FTW_ACTIONRETVAL " (since glibc 2.3.3)"
.RS
.TP
.B FTW_CONTINUE
-Instructs \fBnftw\fP() to continue normally.
+Instructs
+.BR nftw ()
+to continue normally.
.TP
.B FTW_SKIP_SIBLINGS
If \fIfn\fP() returns this value, then
.\" \fIflag\fP set to \fBFTW_DP\fP).
.TP
.B FTW_SKIP_SUBTREE
-If \fIfn\fP() is called with an entry that is a directory
+If \fIfn\fP() is called with an entry that is a directory
(\fItypeflag\fP is \fBFTW_D\fP), this return
value will prevent objects within that directory from being passed as
arguments to \fIfn\fP().
continues processing with the next sibling of the directory.
.TP
.B FTW_STOP
-Causes \fBnftw\fP() to return immediately with the return value
+Causes
+.BR nftw ()
+to return immediately with the return value
\fBFTW_STOP\fP.
.PP
-Other return values could be associated with new actions in the future;
+Other return values could be associated with new actions in the future;
\fIfn\fP() should not return values other than those listed above.
-
-The feature test macro _GNU_SOURCE must be defined in order to
+.PP
+The feature test macro
+.B _GNU_SOURCE
+must be defined
+(before including
+.I any
+header files)
+in order to
obtain the definition of \fBFTW_ACTIONRETVAL\fP from \fI<ftw.h>\fP.
.RE
.TP
to each directory before handling its contents.
This is useful if the program needs to perform some action
in the directory in which \fIfpath\fP resides.
+(Specifying this flag has no effect on the pathname that is passed in the
+.I fpath
+argument of
+.IR fn .)
.TP
.B FTW_DEPTH
If set, do a post-order traversal, that is, call \fIfn\fP() for
(By default, each directory is handled \fIbefore\fP its contents.)
.TP
.B FTW_MOUNT
-If set, stay within the same file system
+If set, stay within the same filesystem
(i.e., do not cross mount points).
.TP
.B FTW_PHYS
If set, do not follow symbolic links.
(This is what you want.)
If not set, symbolic links are followed, but no file is reported twice.
-.sp
-If \fBFTW_PHYS\fP is not set, but \fBFTW_DEPTH\fP is set,
+.IP
+If \fBFTW_PHYS\fP is not set, but \fBFTW_DEPTH\fP is set,
then the function
.IR fn ()
is never called for a directory that would be a descendant of itself.
-.LP
-For each entry in the directory tree,
+.SS ftw()
+.BR ftw ()
+is an older function that offers a subset of the functionality of
+.BR nftw ().
+The notable differences are as follows:
+.IP * 3
+.BR ftw ()
+has no
+.IR flags
+argument.
+It behaves the same as when
.BR nftw ()
-calls
-.IR fn ()
-with four arguments.
-.I fpath
-and
-.I sb
-are as for
-.BR ftw ().
+is called with
+.I flags
+specified as zero.
+.IP *
+The callback function,
+.IR fn (),
+is not supplied with a fourth argument.
+.IP *
+The range of values that is passed via the
.I typeflag
-may receive any of the same values as with
-.BR ftw (),
-or any of the following values:
-.TP
-.B FTW_DP
-.I fpath
-is a directory, and \fBFTW_DEPTH\fP was specified in \fIflags\fP.
-All of the files
-and subdirectories within \fIfpath\fP have been processed.
-.TP
-.B FTW_SL
-.I fpath
-is a symbolic link, and \fBFTW_PHYS\fP was set in \fIflags\fP.
-.TP
-.B FTW_SLN
-.I fpath
-is a symbolic link pointing to a nonexistent file.
-(This occurs only if \fBFTW_PHYS\fP is not set.)
-.LP
-The fourth argument that
-.BR nftw ()
-supplies when calling
-\fIfn\fP()
-is a structure of type \fIFTW\fP:
-.in +0.25i
-.nf
-
-struct FTW {
- int base;
- int level;
-};
-
-.fi
-.in -0.25i
-.I base
-is the offset of the filename (i.e., basename component)
-in the pathname given in
-.IR fpath .
-.IR level
-is the depth of
-.I fpath
-in the directory tree, relative to the root of the tree
-.RI ( dirpath ,
-which has depth 0).
-.SH "RETURN VALUE"
+argument supplied to
+.IR fn ()
+is smaller: just
+.BR FTW_F ,
+.BR FTW_D ,
+.BR FTW_DNR ,
+.BR FTW_NS ,
+and (possibly)
+.BR FTW_SL .
+.SH RETURN VALUE
These functions return 0 on success, and \-1 if an error occurs.
-
-If \fIfn\fP() returns non-zero,
+.PP
+If \fIfn\fP() returns nonzero,
then the tree walk is terminated and the value returned by \fIfn\fP()
-is returned as the result of \fBftw\fP() or \fBnftw\fP().
-
-If \fBnftw\fP() is called with the \fBFTW_ACTIONRETVAL\fP flag,
-then the only non-zero value that should be used by \fIfn\fP()
-to terminate the tree walk is \fBFTW_STOP\fP,
-and that value is returned as the result of \fBnftw\fP().
+is returned as the result of
+.BR ftw ()
+or
+.BR nftw ().
+.PP
+If
+.BR nftw ()
+is called with the \fBFTW_ACTIONRETVAL\fP flag,
+then the only nonzero value that should be used by \fIfn\fP()
+to terminate the tree walk is \fBFTW_STOP\fP,
+and that value is returned as the result of
+.BR nftw ().
+.SH VERSIONS
+.BR nftw ()
+is available under glibc since version 2.1.
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lb lb lb
+l l l.
+Interface Attribute Value
+T{
+.BR nftw ()
+T} Thread safety MT-Safe cwd
+T{
+.BR ftw ()
+T} Thread safety MT-Safe
+.TE
+.sp 1
+.SH CONFORMING TO
+POSIX.1-2001, POSIX.1-2008, SVr4, SUSv1.
+POSIX.1-2008 marks
+.BR ftw ()
+as obsolete.
.SH NOTES
+POSIX.1-2008 notes that the results are unspecified if
+.I fn
+does not preserve the current working directory.
+.PP
The function
.BR nftw ()
and the use of \fBFTW_SL\fP with
.BR ftw ()
were introduced in SUSv1.
-.LP
-On some systems
+.PP
+In some implementations (e.g., glibc),
.BR ftw ()
will never use \fBFTW_SL\fP, on other systems \fBFTW_SL\fP occurs only
for symbolic links that do not point to an existing file,
and again on other systems
.BR ftw ()
-will use \fBFTW_SL\fP for each symbolic link. For predictable control, use
+will use \fBFTW_SL\fP for each symbolic link.
+If
+.I fpath
+is a symbolic link and
+.BR stat (2)
+failed, POSIX.1-2008 states
+that it is undefined whether \fBFTW_NS\fP or \fBFTW_SL\fP
+is passed in
+.IR typeflag .
+For predictable results, use
.BR nftw ().
-.LP
-Under Linux, libc4 and libc5 and glibc 2.0.6 will
-use \fBFTW_F\fP for all objects (files, symbolic links, fifos, etc)
-that can be stat'ed but are not a directory.
-
-The function
-.BR nftw ()
-is available since glibc 2.1.
-
-\fBFTW_ACTIONRETVAL\fP is glibc specific.
-.SH "CONFORMING TO"
-POSIX.1-2001, SVr4, SUSv1.
+.SH BUGS
+In the specification of
+.BR nftw (),
+POSIX.1 notes that when
+.B FTW_NS
+is passed as the
+.I typeflag
+argument of
+.IR fn (),
+then the contents of the buffer pointed to by the
+.I sb
+argument are undefined.
+The standard makes no such statement for the case where
+.B FTW_SLN
+is passed in
+.IR typeflag ,
+with the implication that the contents of the buffer pointed to by
+.I sb
+are defined.
+And indeed this is the case on most implementations: the buffer pointed to by
+.I sb
+contains the results produced by applying
+.BR lstat (2)
+to the symbolic link.
+In early glibc, the behavior was the same.
+However, since glibc 2.4, the contents of the buffer pointed to by
+.I sb
+are undefined when
+.B FTW_SLN
+is passed in
+.IR typeflag .
+This change
+.I appears
+to be an unintended regression,
+but it is not (yet) clear if the behavior will be restored to that
+provided in the original glibc implementation (and on other implementations).
+.\" FIXME .
+.\" https://bugzilla.redhat.com/show_bug.cgi?id=1422736
+.\" http://austingroupbugs.net/view.php?id=1121
.SH EXAMPLE
The following program traverses the directory tree under the path named
in its first command-line argument, or under the current directory
if no argument is supplied.
It displays various information about each file.
-The second-command line argument can be used to specify characters that
-control the value assigned to the \fIflags\fP
-argument when calling \fBnftw\fP().
-.nf
-
+The second command-line argument can be used to specify characters that
+control the value assigned to the \fIflags\fP
+argument when calling
+.BR nftw ().
+.SS Program source
+\&
+.EX
#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
static int
-display_info(const char *fpath, const struct stat *sb,
+display_info(const char *fpath, const struct stat *sb,
int tflag, struct FTW *ftwbuf)
{
- printf("%-3s %2d %7lld %-40s %d %s\\n",
- (tflag == FTW_D) ? "d" : (tflag == FTW_DNR) ? "dnr" :
- (tflag == FTW_DP) ? "dp" : (tflag == FTW_F) ? "f" :
- (tflag == FTW_DP) ? "dp" : (tflag == FTW_SL) ? "sl" :
- (tflag == FTW_SLN) ? "sln" : "???",
- ftwbuf->level, (long long) sb->st_size,
- fpath, ftwbuf->base, fpath + ftwbuf->base);
+ printf("%\-3s %2d ",
+ (tflag == FTW_D) ? "d" : (tflag == FTW_DNR) ? "dnr" :
+ (tflag == FTW_DP) ? "dp" : (tflag == FTW_F) ? "f" :
+ (tflag == FTW_NS) ? "ns" : (tflag == FTW_SL) ? "sl" :
+ (tflag == FTW_SLN) ? "sln" : "???",
+ ftwbuf\->level);
+
+ if (tflag == FTW_NS)
+ printf("\-\-\-\-\-\-\-");
+ else
+ printf("%7jd", (intmax_t) sb\->st_size);
+
+ printf(" %\-40s %d %s\en",
+ fpath, ftwbuf\->base, fpath + ftwbuf\->base);
+
return 0; /* To tell nftw() to continue */
}
{
int flags = 0;
- if (argc > 2 && strchr(argv[2], 'd') != NULL)
+ if (argc > 2 && strchr(argv[2], \(aqd\(aq) != NULL)
flags |= FTW_DEPTH;
- if (argc > 2 && strchr(argv[2], 'p') != NULL)
+ if (argc > 2 && strchr(argv[2], \(aqp\(aq) != NULL)
flags |= FTW_PHYS;
- nftw((argc < 2) ? "." : argv[1], display_info, 20, flags);
+ if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags)
+ == \-1) {
+ perror("nftw");
+ exit(EXIT_FAILURE);
+ }
+
exit(EXIT_SUCCESS);
}
-.fi
-.SH "SEE ALSO"
+.EE
+.SH SEE ALSO
.BR stat (2),
.BR fts (3),
.BR readdir (3)