aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cftw.c20
-rw-r--r--cftw.h3
-rw-r--r--main.c6
3 files changed, 19 insertions, 10 deletions
diff --git a/cftw.c b/cftw.c
index 8fb1d67..4b8b013 100644
--- a/cftw.c
+++ b/cftw.c
@@ -9,8 +9,8 @@
#include <stdint.h>
#include <string.h>
-int cftw(const char *const dirpath, int (*const fn)(const char *,
- const struct stat *, void *), void *const user)
+static int do_cftw(const char *const dirpath, int (*const fn)(const char *,
+ const struct stat *, bool *, void *), bool *const done, void *const user)
{
int ret = -1;
DIR *const d = opendir(dirpath);
@@ -58,20 +58,20 @@ int cftw(const char *const dirpath, int (*const fn)(const char *,
__func__, path, strerror(errno));
else if (S_ISDIR(sb.st_mode))
{
- if ((ret = cftw(d.str, fn, user)))
+ if ((ret = do_cftw(d.str, fn, done, user)))
;
- else if ((ret = fn(d.str, &sb, user)))
+ else if ((ret = fn(d.str, &sb, done, user)))
;
}
else if (S_ISREG(sb.st_mode))
- ret = fn(d.str, &sb, user);
+ ret = fn(d.str, &sb, done, user);
else
fprintf(stderr, "%s: unexpected st_mode %ju\n",
__func__, (uintmax_t)sb.st_mode);
dynstr_free(&d);
- if (ret)
+ if (ret || *done)
goto end;
}
@@ -87,3 +87,11 @@ end:
return ret;
}
+
+int cftw(const char *const dirpath, int (*const fn)(const char *,
+ const struct stat *, bool *, void *), void *const user)
+{
+ bool done = false;
+
+ return do_cftw(dirpath, fn, &done, user);
+}
diff --git a/cftw.h b/cftw.h
index 612451e..663960c 100644
--- a/cftw.h
+++ b/cftw.h
@@ -1,11 +1,12 @@
#ifndef CFTW_H
#define CFTW_H
+#include <stdbool.h>
#include <sys/stat.h>
/* Thread-safe variant of ftw(3) and nftw(3) that allows passing an
* opaque pointer and removes some unneeded parameters. */
int cftw(const char *dirpath, int (*fn)(const char *fpath,
- const struct stat *sb, void *user), void *user);
+ const struct stat *sb, bool *done, void *user), void *user);
#endif /* CFTW_H */
diff --git a/main.c b/main.c
index b75d556..19178f4 100644
--- a/main.c
+++ b/main.c
@@ -619,7 +619,7 @@ struct search_args
};
static int search_fn(const char *const fpath, const struct stat *const sb,
- void *const user)
+ bool *const done, void *const user)
{
const struct search_args *const sa = user;
const char *rel = fpath + strlen(sa->root);
@@ -810,7 +810,7 @@ end:
}
static int add_length(const char *const fpath, const struct stat *const sb,
- void *const user)
+ bool *const done, void *const user)
{
if (!S_ISREG(sb->st_mode))
return 0;
@@ -1481,7 +1481,7 @@ static const char *find_rm_dir(const struct form *const forms, const size_t n,
}
static int rm_dir_contents(const char *const fpath,
- const struct stat *const sb, void *const user)
+ const struct stat *const sb, bool *const done, void *const user)
{
if (S_ISDIR(sb->st_mode) && rmdir(fpath))
{