- Enable GNU Source before any include directives.
#define _GNU_SOURCE
- Before calling
nftw() enable FTW_ACTIONRETVAL in the flags. This enables nftw() to recourse its execution based on return values from callback_function().
/* snippet from nftw manpage */
#define MAX_OPEN_FDS 64
flags |= FTW_ACTIONRETVAL; // enables callback_function() to recourse
if (nftw ((argc < 2) ? "." : argv[1], callback_function, MAX_OPEN_FDS, flags)
== -1) {
perror ("nftw");
exit (EXIT_FAILURE);
}
- In the
callback_function() at the beginning itself skip the directory if it's above desired level.
#define DEPTH_LIMIT 1
/*
...
*/
int
callback_function (const char *fpath, const struct stat *sb,
int tflag, struct FTW *ftwbuf) {
// works even when FTW_DEPTH is enabled.
// at the top first condition to check;
if (ftwbuf->level > DEPTH_LIMIT) return FTW_SKIP_SIBLINGS;
/*
...
*/
return FTW_CONTINUE;
}
Whenever nftw() returns with a file in a directory crossing the DEPTH_LIMIT, FTW_SKIP_SIBLINGS instructs it to skip that directory and continue with siblings in parent directory.
If you omit FTW_DEPTH in nftw() flags, you can use FTW_SKIP_SUBTREE feature; where nftw() skips a directory right away.
FTW_DEPTH instructs nftw() to pass the directory itself after going through all files & sub-directories in it. This post-order traversal of directories makes it difficult to use FTW_SKIP_SUBTREE;
// without `FTW_DEPTH` in nftw-flags
int
callback_function (const char *fpath, const struct stat *sb,
int tflag, struct FTW *ftwbuf) {
/*
...
*/
if (DEPTH_LIMIT == ftwbuf->level && FTW_D == tflag) // a directory
return FTW_SKIP_SUBTREE; // don't get into the directory
else
return FTW_CONTINUE;
}