ftw.3: Reorganize the page to give primacy to nftw()

nftw() is the better API, and POSIX.1-2008 marks ftw() obsolete.

Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
Michael Kerrisk 2015-04-17 20:47:24 +02:00
parent 3591ce3e19
commit d954cea8fd
1 changed files with 125 additions and 121 deletions

View File

@ -33,31 +33,35 @@
.\" 2006-05-24, Michael Kerrisk <mtk.manpages@gmail.com> .\" 2006-05-24, Michael Kerrisk <mtk.manpages@gmail.com>
.\" Added an example program. .\" Added an example program.
.\" .\"
.\" FIXME: This page should be rewritten to first of all describe
.\" nftw() and then describe the differnces in the older ftw().
.\"
.TH FTW 3 2014-12-31 "Linux" "Linux Programmer's Manual" .TH FTW 3 2014-12-31 "Linux" "Linux Programmer's Manual"
.SH NAME .SH NAME
ftw, nftw \- file tree walk ftw, nftw \- file tree walk
.SH SYNOPSIS .SH SYNOPSIS
.nf .nf
.B #include <ftw.h> .B #include <ftw.h>
.sp
.BI "int ftw(const char *" dirpath ,
.BI " int (*" fn ") (const char *" fpath ", const struct stat *" sb ,
.BI " int " typeflag ),
.BI " int " nopenfd );
.sp
.BR "#define _XOPEN_SOURCE 500" " /* See feature_test_macros(7) */"
.B #include <ftw.h>
.sp
.BI "int nftw(const char *" dirpath , .BI "int nftw(const char *" dirpath ,
.BI " int (*" fn ") (const char *" fpath ", const struct stat *" sb , .BI " int (*" fn ") (const char *" fpath ", const struct stat *" sb ,
.BI " int " typeflag ", struct FTW *" ftwbuf ), .BI " int " typeflag ", struct FTW *" ftwbuf ),
.BI " int " nopenfd ", int " flags ); .BI " int " nopenfd ", int " flags );
.B #include <ftw.h>
.BI "int ftw(const char *" dirpath ,
.BI " int (*" fn ") (const char *" fpath ", const struct stat *" sb ,
.BI " int " typeflag ),
.BI " int " nopenfd );
.fi .fi
.sp
.in -4n
Feature Test Macro Requirements for glibc (see
.BR feature_test_macros (7)):
.in
.sp
.BR nftw ():
_XOPEN_SOURCE >= 500
.SH DESCRIPTION .SH DESCRIPTION
.BR ftw () .BR nftw ()
walks through the directory tree that is walks through the directory tree that is
located under the directory \fIdirpath\fP, located under the directory \fIdirpath\fP,
and calls \fIfn\fP() once for each entry in the tree. and calls \fIfn\fP() once for each entry in the tree.
@ -66,30 +70,31 @@ subdirectories they contain (preorder traversal).
To avoid using up all of the calling process's file descriptors, To avoid using up all of the calling process's file descriptors,
\fInopenfd\fP specifies the maximum number of directories that \fInopenfd\fP specifies the maximum number of directories that
.BR ftw () .BR nftw ()
will hold open simultaneously. will hold open simultaneously.
When When
the search depth exceeds this, the search depth exceeds this,
.BR ftw () .BR nftw ()
will become slower because will become slower because
directories have to be closed and reopened. directories have to be closed and reopened.
.BR ftw () .BR nftw ()
uses at most uses at most
one file descriptor for each level in the directory tree. one file descriptor for each level in the directory tree.
For each entry found in the tree, For each entry found in the tree,
.BR ftw () .BR nftw ()
calls calls
\fIfn\fP() with three arguments: \fIfn\fP() with four arguments:
.IR fpath , .IR fpath ,
.IR sb , .IR sb ,
.IR typeflag ,
and and
.IR typeflag . .IR ftwbuf .
.I fpath .I fpath
is the pathname of the entry, is the pathname of the entry,
and is expressed either as a pathname relative to the calling process's and is expressed either as a pathname relative to the calling process's
current working directory at the time of the call to current working directory at the time of the call to
.BR ftw (), .BR nftw (),
if if
.IR dirpath .IR dirpath
was expressed as a relative pathname, was expressed as a relative pathname,
@ -118,6 +123,20 @@ is a directory.
.I fpath .I fpath
is a directory which can't be read. is a directory which can't be read.
.TP .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 .B FTW_NS
The The
.BR stat (2) .BR stat (2)
@ -131,27 +150,54 @@ could be seen,
but did not have execute permission, but did not have execute permission,
so that the file could not be reached for so that the file could not be reached for
.BR stat (2). .BR stat (2).
.sp .TP
If .B FTW_SL
.I fpath .I fpath
is a symbolic link and is a symbolic link, and \fBFTW_PHYS\fP was set in \fIflags\fP.
.BR stat (2) .\" To obtain the definition of this constant from
failed, POSIX.1-2008 states .\" .IR <ftw.h> ,
that it is undefined whether \fBFTW_NS\fP or \fBFTW_SL\fP (see below) .\" either
is passed in .\" .B _BSD_SOURCE
.IR typeflag . .\" must be defined, or
(For the more modern .\" .BR _XOPEN_SOURCE
.BR nftw (), .\" must be defined with a value of 500 or more.
described below, .TP
the bahavior is defined: .B FTW_SLN
.BR FTW_NS .I fpath
is returned for this case.) is a symbolic link pointing to a nonexistent file.
(This occurs only if \fBFTW_PHYS\fP is not set.)
.PP
The fourth argument that
.BR nftw ()
supplies when calling
\fIfn\fP()
is a structure of type \fIFTW\fP:
.in +4n
.nf
struct FTW {
int base;
int level;
};
.fi
.in
.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 .PP
To stop the tree walk, \fIfn\fP() returns a nonzero value; this To stop the tree walk, \fIfn\fP() returns a nonzero value; this
value will become the return value of value will become the return value of
.BR ftw (). .BR nftw ().
As long as \fIfn\fP() returns 0, As long as \fIfn\fP() returns 0,
.BR ftw () .BR nftw ()
will continue either until it has traversed the entire tree, will continue either until it has traversed the entire tree,
in which case it will return zero, in which case it will return zero,
or until it encounters an error (such as a or until it encounters an error (such as a
@ -159,7 +205,7 @@ or until it encounters an error (such as a
failure), in which case it will return \-1. failure), in which case it will return \-1.
.PP .PP
Because Because
.BR ftw () .BR nftw ()
uses dynamic data structures, the only safe way to uses dynamic data structures, the only safe way to
exit out of a tree walk is to return a nonzero value from \fIfn\fP(). 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, To allow a signal to terminate the walk without causing a memory leak,
@ -167,15 +213,10 @@ have the handler set a global flag that is checked by \fIfn\fP().
\fIDon't\fP use \fIDon't\fP use
.BR longjmp (3) .BR longjmp (3)
unless the program is going to terminate. unless the program is going to terminate.
.SS nftw()
The function
.BR nftw ()
is the same as
.BR ftw (),
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 The \fIflags\fP argument of
.BR nftw ()
is formed by ORing zero or more of the
following flags: following flags:
.TP .TP
.BR FTW_ACTIONRETVAL " (since glibc 2.3.3)" .BR FTW_ACTIONRETVAL " (since glibc 2.3.3)"
@ -258,77 +299,37 @@ If \fBFTW_PHYS\fP is not set, but \fBFTW_DEPTH\fP is set,
then the function then the function
.IR fn () .IR fn ()
is never called for a directory that would be a descendant of itself. is never called for a directory that would be a descendant of itself.
.LP .SS ftw()
For each entry in the directory tree, .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 () .BR nftw ()
calls 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
argument supplied to
.IR fn () .IR fn ()
with four arguments. is smaller: just
.I fpath .BR FTW_F ,
and .BR FTW_D ,
.I sb .BR FTW_DNR ,
are as for .BR FTW_NS ,
.BR ftw (). and (possibly)
.I typeflag .BR FTW_SL .
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.
(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_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.)
.LP
The fourth argument that
.BR nftw ()
supplies when calling
\fIfn\fP()
is a structure of type \fIFTW\fP:
.in +4n
.nf
struct FTW {
int base;
int level;
};
.fi
.in
.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).
.SH RETURN VALUE .SH RETURN VALUE
These functions return 0 on success, and \-1 if an error occurs. These functions return 0 on success, and \-1 if an error occurs.
@ -365,20 +366,23 @@ and the use of \fBFTW_SL\fP with
.BR ftw () .BR ftw ()
were introduced in SUSv1. were introduced in SUSv1.
.LP .LP
On some systems In some implementations (e.g., glibc),
.BR ftw () .BR ftw ()
will never use \fBFTW_SL\fP, on other systems \fBFTW_SL\fP occurs only 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, for symbolic links that do not point to an existing file,
and again on other systems and again on other systems
.BR ftw () .BR ftw ()
will use \fBFTW_SL\fP for each symbolic link. will use \fBFTW_SL\fP for each symbolic link.
For predictable control, use 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 (). .BR nftw ().
.LP
\fBFTW_F\fP is returned for all objects (files, symbolic links, FIFOs, etc.)
that can be stat'ed but are not a directory.
\fBFTW_ACTIONRETVAL\fP is glibc-specific.
.SH EXAMPLE .SH EXAMPLE
The following program traverses the directory tree under the path named The following program traverses the directory tree under the path named
in its first command-line argument, or under the current directory in its first command-line argument, or under the current directory