Search code examples
clinuxfiletreenftw

Skip subdirectories when using ntfw in c


I am trying to get all the files and directories in the current or mentioned folder using nftw. But how do I instruct the function not to go further in any subdirectory? What is the purpose of the flag FTW_SKIP_SUBTREE? Also what is the header file for this constant.

#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,
             int tflag, struct FTW *ftwbuf)
{

    printf("%-3s %2d %7jd   %-40s %d %s\n",
        (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, (intmax_t) sb->st_size,
        fpath, ftwbuf->base, fpath + ftwbuf->base);
    return 0;           /* To tell nftw() to continue */
}

int
main(int argc, char *argv[])
{
    int flags = 0;

    if (argc > 2 && strchr(argv[2], 'd') != NULL)
      flags |= FTW_DEPTH;
    if (argc > 2 && strchr(argv[2], 'p') != NULL)
      flags |= FTW_PHYS;
    if (argc > 2 && strchr(argv[2], 's') != NULL)
      flags |= FTW_SKIP_SUBTREE;

    if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags)
            == -1) {
        perror("nftw");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

When I try to compile I get this message

test.c:33:16: error: ‘FTW_SKIP_SUBTREE’ undeclared (first use in this function)
       flags |= FTW_SKIP_SUBTREE;

Solution

  • The manual page for nftw() on Linux says (in part):

    nftw()

    The function nftw() is the same as ftw(), except that it has one additional argument, flags, and calls fn() with one more argument, ftwbuf.

    This flags argument is formed by ORing zero or more of the following flags:

    • FTW_ACTIONRETVAL (since glibc 2.3.3)
      If this glibc-specific flag is set, then nftw() handles the return value from fn() differently. fn() should return one of the following values:

      • FTW_CONTINUE Instructs nftw() to continue normally.

      • FTW_SKIP_SIBLINGS
        If fn() returns this value, then siblings of the current entry will be skipped, and processing continues in the parent.

      • FTW_SKIP_SUBTREE
        If fn() is called with an entry that is a directory (typeflag is FTW_D), this return value will prevent objects within that directory from being passed as arguments to fn(). nftw() continues processing with the next sibling of the directory.

      • FTW_STOP
        Causes nftw() to return immediately with the return value FTW_STOP.

      • Other return values could be associated with new actions in the future; fn() should not return values other than those listed above.

      The feature test macro _GNU_SOURCE must be defined in order to obtain the definition of FTW_ACTIONRETVAL from <ftw.h>.

    The last paragraph is the crucial one for you to note.