Walking a Directory Structure

Some UNIX platforms provide the function ftw(3C) and the newer function nftw(3C) to make it simpler to perform a tree walk of a file system. These functions do not appear on the FreeBSD system, so only a cursory description of them will be provided here. The HPUX-11 ftw(3C) page provides this function synopsis:

#include <ftw.h>

int ftw (const char *path,
    int (*fn)(const char *obj_path,
        const struct stat *obj_stat,
        int obj_flags),
    int depth);

int nftw (const char *path,
    int (*fn)(const char *obj_path,
        const struct stat *obj_stat,
        int obj_flags,
        struct FTW obj_FTW),
    int depth,
    int flags);

These functions start by examining the directory provided by the argument path. From this point on, the directory is recursively searched for subdirectories until all file system objects under path have been processed.

Both of these functions also require a pointer to a function fn that will be called for each file system object being considered.

The depth argument determines how many levels deep the tree will be traversed. HP's documentation indicates that this will also be limited by "the number of file descriptors currently available for use." A negative or zero value for the depth argument is equivalent to specifying depth=1.

The nftw(3C) function accepts an additional flags argument. This argument accepts values like FTW_DEPTH to cause a depth-first tree walk to be performed. Flag FTW_PHYS is useful because it prevents the tree walk from following symlinks. This prevents the tree walk from visiting files more than once. See Table 7.1 for a complete list of these flags.

Table 7.1. Macro Names of nftw(3C) Flags
Macro Name Description
FTW_PHYS Causes nftw(3C) to perform a physical walk. No symbolic links are followed. Hard links are followed unless the path crosses itself. When FTW_PHYS is not given, nftw(3C) follows symbolic and hard links but does not walk a path that crosses itself.
FTW_MOUNT The tree walk will not cross a mount point. Only files on the same mounted device as the starting path are considered.
FTW_DEPTH A depth-first walk is performed, causing a directory's entries to be visited before the directory itself.
FTW_CHDIR A call to chdir(2) is performed prior to reading the directory being visited.
FTW_SERR The tree walk normally exits with a return value of -1 if lstat(2) fails (error code in errno). When FTW_SERR is specified, a failure of lstat(2) causes the function fn to be called, and the tree walk is allowed to continue.

The ftw(3C) and nftw(3C) functions call a user-supplied function fn. The function fn that is called by ftw(3C) looks like this:

int fn(const char *obj_path,       /* Pathname of object */
    const struct stat *obj_stat,   /* struct stat info */
    int obj_flags);                /* flag bits */

The obj_path argument contains the pathname of the object being considered, and obj_stat is a pointer to a stat structure describing the object. The additional flags in argument obj_flags are provided and contain the values shown in Table 7.2.

Table 7.2. Table of ftw(3C) and nftw(3C) obj_flags
Macro Description
FTW_F Object is a file.
FTW_D Object is a directory.
FTW_SL Object is a symbolic link (nftw(3C) only).
FTW_DNR is a directory without read permission. Function fn will not be called for any of its descendants.
FTW_NS lstat(2) failed to obtain information about the object, leaving the stat structure contents undefined. For ftw(3C), if the failure is because the directory containing the object could not be searched, fn is called and the walk continues. For nftw(3C), the value for errno is set, and nftw(3C) returns -1 after calling fn, instead. Other lstat(2) failures cause fn not to be called, and the value -1 is returned, with errno set. This behavior is modified by the nftw(3C) flag FTW_SERR.

The function nftw(3C) calls a slightly different user-supplied function fn. Its definition includes an additional argument named obj_FTW:

int fn(const char *obj_path,       /* pathname of object */
    const struct stat *obj_stat,   /* struct stat info */
    int obj_flags,                 /* flag bits */
    struct FTW *obj_FTW);          /* additional info */

The structure FTW contains the following members:

struct FTW {
    int    base;   /* Offset into pathname to the start of the basename */
    int    level;  /* Relative depth level (root is level 0) */
    /* private members.. */
};

The only members of struct FTW that should be used are the base and level members. Other members of the structure, if present, are not portable to all platforms. If function fn is called with the arguments obj_path and the argument obj_FTW as shown earlier, then the basename of the object can be displayed as follows:

printf("Basename = '%s'
",obj_path+obj_FTW->base);

If your application must be portable to the widest possible range of UNIX platforms, then you would be wise to avoid the ftw(3C) and nftw(3C) functions. These will be found on most SysV-derived UNIX platforms but may not exist on a BSD-derived UNIX.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.160.216