summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2015-06-18 23:35:43 -0400
committerTavian Barnes <tavianator@tavianator.com>2015-06-18 23:35:43 -0400
commitac11476e20136976bf689acf847fdcea4e05e37a (patch)
tree00479528e76f3af42645635da0fa959f784eecfc
parent3f7290f5fd7b5c441b35896dfa3333e2f4989ea4 (diff)
downloadbfs-ac11476e20136976bf689acf847fdcea4e05e37a.tar.xz
bftw: Add flags parameter and BFTW_STAT flag.
-rw-r--r--bfs.c4
-rw-r--r--bftw.c12
-rw-r--r--bftw.h13
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 <sys/stat.h>
+
/**
* 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)