1

In C, is there a way to specify the maximum depth from the base directory that nftw will search? For example, say the directory dir that I want to search has a sub-subdirectory, but I only want nftw to search through subdir and not sub-subdir, or anything below that.

dir
 \_ subdir
    |__ file1
    |__ file2
     \_ sub-subdir
        |__ file1
        |__ file2
         \_ file3
petew
  • 671
  • 8
  • 13

2 Answers2

2

According to the manual page (http://man7.org/linux/man-pages/man3/nftw.3.html) you can stop to go in subdirectories from inside the function argument.

From the example reported in the manual with a limitation to 2 levels in subdirs the source code is:

#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>


// max num of sub dirs
#define MAXLEVEL  2

static int display_info(const char *fpath, const struct stat *sb,
            int tflag, struct FTW *ftwbuf)
{
   // if the depth is above the max sub dirs, continue to next file
   if (ftwbuf->level > MAXLEVEL) {
       return 0; 
   }
   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 (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags) == -1) {
       perror("nftw");
       exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
}
petew
  • 671
  • 8
  • 13
gaetanoM
  • 41,594
  • 6
  • 42
  • 61
  • 1
    It still iterate over all the files, thus no performance . think if there are 10 files in level 2, but 1000000 files in all levels , the `display_info()` will still be called 1000000 times . – neoedmund Oct 15 '21 at 03:36
  • see https://www.man7.org/linux/man-pages/man3/fts.3.html – neoedmund Oct 15 '21 at 04:24
  • @neoedmund Yes, right. But the question is related to **nftw** – gaetanoM Oct 15 '21 at 14:15
0

If you don't mind using glibc-specific implementation, add FTW_ACTIONRETVAL to the 4th parameter to nftw(), then return FTW_SKIP_SIBLINGS (instead of 0) in your callback if the ftw->level is more than your depth.

amme
  • 1
  • 1