aboutsummaryrefslogtreecommitdiff
path: root/dir.c
diff options
context:
space:
mode:
authorDerrick Stolee <stolee@gmail.com>2025-09-12 10:30:08 +0000
committerJunio C Hamano <gitster@pobox.com>2025-09-12 08:59:52 -0700
commit1588e836bb956d14e6cb38e35933ed2749c023b4 (patch)
tree4da578844afe9c2fd369aaf6db0cdbc56f933108 /dir.c
parenta8077c19131a86fa123c5be2c8b735acdb5dacf4 (diff)
downloadgit-1588e836bb956d14e6cb38e35933ed2749c023b4.tar.xz
dir: add generic "walk all files" helper
There is sometimes a need to visit every file within a directory, recursively. The main example is remove_dir_recursively(), though it has some extra flags that make it want to iterate over paths in a custom way. There is also the fill_directory() approach but that involves an index and a pathspec. This change adds a new for_each_file_in_dir() method that will be helpful in the next change. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'dir.c')
-rw-r--r--dir.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/dir.c b/dir.c
index dfb4d40103..7731f7b9d3 100644
--- a/dir.c
+++ b/dir.c
@@ -30,6 +30,7 @@
#include "read-cache-ll.h"
#include "setup.h"
#include "sparse-index.h"
+#include "strbuf.h"
#include "submodule-config.h"
#include "symlinks.h"
#include "trace2.h"
@@ -87,6 +88,33 @@ struct dirent *readdir_skip_dot_and_dotdot(DIR *dirp)
return e;
}
+int for_each_file_in_dir(struct strbuf *path, file_iterator fn, const void *data)
+{
+ struct dirent *e;
+ int res = 0;
+ size_t baselen = path->len;
+ DIR *dir = opendir(path->buf);
+
+ if (!dir)
+ return 0;
+
+ while (!res && (e = readdir_skip_dot_and_dotdot(dir)) != NULL) {
+ unsigned char dtype = get_dtype(e, path, 0);
+ strbuf_setlen(path, baselen);
+ strbuf_addstr(path, e->d_name);
+
+ if (dtype == DT_REG) {
+ res = fn(path->buf, data);
+ } else if (dtype == DT_DIR) {
+ strbuf_addch(path, '/');
+ res = for_each_file_in_dir(path, fn, data);
+ }
+ }
+
+ closedir(dir);
+ return res;
+}
+
int count_slashes(const char *s)
{
int cnt = 0;