From ac11476e20136976bf689acf847fdcea4e05e37a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 18 Jun 2015 23:35:43 -0400 Subject: bftw: Add flags parameter and BFTW_STAT flag. --- bfs.c | 4 ++-- bftw.c | 12 ++++++++---- bftw.h | 13 +++++++++++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/bfs.c b/bfs.c index 7a7b789..6c0e07c 100644 --- a/bfs.c +++ b/bfs.c @@ -20,7 +20,7 @@ typedef struct { bool hidden; } options; -static int callback(const char *fpath, int typeflag, void *ptr) { +static int callback(const char *fpath, const struct stat *sb, int typeflag, void *ptr) { const options *opts = ptr; const char *filename = strrchr(fpath, '/'); @@ -64,7 +64,7 @@ int main(int argc, char* argv[]) { } // TODO: getrlimit(RLIMIT_NOFILE) - if (bftw(opts.path, callback, 1024, &opts) != 0) { + if (bftw(opts.path, callback, 1024, 0, &opts) != 0) { perror("bftw()"); return EXIT_FAILURE; } diff --git a/bftw.c b/bftw.c index e8228c6..0d55a65 100644 --- a/bftw.c +++ b/bftw.c @@ -368,7 +368,7 @@ static dircache_entry *dirqueue_pop(dirqueue *queue) { return entry; } -int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, void *ptr) { +int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, int flags, void *ptr) { int ret = -1, err; dircache cache; @@ -419,9 +419,13 @@ int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, void *ptr) { } #endif - if (typeflag == BFTW_UNKNOWN) { - struct stat sb; + struct stat sb; + struct stat *sp = NULL; + + if ((flags & BFTW_STAT) || typeflag == BFTW_UNKNOWN) { if (fstatat(dirfd(dir), de->d_name, &sb, AT_SYMLINK_NOFOLLOW) == 0) { + sp = &sb; + switch (sb.st_mode & S_IFMT) { case S_IFDIR: typeflag = BFTW_D; @@ -436,7 +440,7 @@ int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, void *ptr) { } } - int action = fn(path.str, typeflag, ptr); + int action = fn(path.str, sp, typeflag, ptr); switch (action) { case BFTW_CONTINUE: diff --git a/bftw.h b/bftw.h index be538a8..09c7943 100644 --- a/bftw.h +++ b/bftw.h @@ -9,11 +9,15 @@ * the COPYING file or http://www.wtfpl.net/ for more details. * *********************************************************************/ +#include + /** * Callback function type for bftw(). * * @param fpath * The path to the encountered file. + * @param sb + * A stat() buffer; may be NULL if no stat() call was needed. * @param typeflag * A typeflag value (see below). * @param ptr @@ -21,7 +25,7 @@ * @return * An action value (see below). */ -typedef int bftw_fn(const char *fpath, int typeflag, void *ptr); +typedef int bftw_fn(const char *fpath, const struct stat *sb, int typeflag, void *ptr); /** * Breadth First Tree Walk (or Better File Tree Walk). @@ -36,12 +40,14 @@ typedef int bftw_fn(const char *fpath, int typeflag, void *ptr); * The callback to invoke. * @param nopenfd * The maximum number of file descriptors to keep open. + * @param flags + * Flags that control bftw() behavior (see below). * @param ptr * A generic pointer which is passed to fn(). * @return * 0 on success, or -1 on failure. */ -int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, void *ptr); +int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, int flags, void *ptr); /** typeflag: Directory. */ #define BFTW_D 0 @@ -60,3 +66,6 @@ int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, void *ptr); #define BFTW_SKIP_SUBTREE 2 /** action: Stop walking. */ #define BFTW_STOP 3 + +/** flag: stat() each encountered file. */ +#define BFTW_STAT (1 << 0) -- cgit v1.2.3