From 62d5bcbd4970f45447ea7fe8e9c5db0283a3aea5 Mon Sep 17 00:00:00 2001 From: Paul Edmon Date: Tue, 27 Jun 2023 11:51:42 -0400 Subject: [PATCH 1/2] Update dftw.c Changing order so that it will get definitions prior to libcircle.h --- libdftw/dftw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdftw/dftw.c b/libdftw/dftw.c index 2193c07..21eef0c 100644 --- a/libdftw/dftw.c +++ b/libdftw/dftw.c @@ -1,8 +1,8 @@ +#include #include #include #include -#include #include #include #include From 64d705b2cc1c666a030056dacaae6962f3133b34 Mon Sep 17 00:00:00 2001 From: Nathan Weeks <1800812+nathanweeks@users.noreply.github.com> Date: Mon, 20 Apr 2026 18:57:32 -0400 Subject: [PATCH 2/2] Support subtree pruning from dftw callbacks (#1) Makes it possible for fscull to skip internal trash or exempt subtrees during traversal and avoids races and hangs caused by traversing directories that are being populated during the same run --- libdftw.h | 8 ++++++++ libdftw/dftw.c | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libdftw.h b/libdftw.h index 4aa7a0d..2666b85 100644 --- a/libdftw.h +++ b/libdftw.h @@ -16,6 +16,14 @@ enum { #define FTW_NS FTW_NS }; +#define DFTW_CONTINUE 0 +#define DFTW_SKIP_SUBTREE 1 + +/* + * Callbacks should return DFTW_CONTINUE to continue traversal. Returning + * DFTW_SKIP_SUBTREE from an FTW_D callback skips descending into that + * directory while allowing the walk to continue elsewhere. + */ void dftw(const char *dirpath, int (*fn) (const char *fpath, const struct stat *sb, int typeflag)); diff --git a/libdftw/dftw.c b/libdftw/dftw.c index 21eef0c..795e7de 100644 --- a/libdftw/dftw.c +++ b/libdftw/dftw.c @@ -36,6 +36,7 @@ void DFTW_create(CIRCLE_handle* handle) void DFTW_process(CIRCLE_handle* handle) { struct stat st; + int cb_rc = DFTW_CONTINUE; int status = 0; char temp[CIRCLE_MAX_STRING_LEN]; @@ -51,8 +52,10 @@ void DFTW_process(CIRCLE_handle* handle) } else if(S_ISDIR(st.st_mode) && !(S_ISLNK(st.st_mode))) { - _DFTW_CB(temp, &st, FTW_D); - DFTW_process_dir(temp, handle); + cb_rc = _DFTW_CB(temp, &st, FTW_D); + if(cb_rc == DFTW_CONTINUE) { + DFTW_process_dir(temp, handle); + } } else if(S_ISREG(st.st_mode)) { _DFTW_CB(temp, &st, FTW_F);