From 54a0f854a764b94490a1ecd8cde9fbe70de6a3bb Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Mon, 28 Sep 2015 02:38:55 -0700 Subject: [PATCH] Avoid FTS (broken in glibc, not present on Win32). --- ldid.cpp | 76 ++++++++++++++++++++++++++++---------------------------- ldid.hpp | 2 ++ 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/ldid.cpp b/ldid.cpp index 374dfcd..1a3dadf 100644 --- a/ldid.cpp +++ b/ldid.cpp @@ -29,9 +29,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -1563,6 +1563,42 @@ DiskFolder::~DiskFolder() { Commit(commit.first, commit.second); } +void DiskFolder::Find(const std::string &root, const std::string &base, const Functor &)> &)>&code) { + std::string path(Path(root) + base); + + DIR *dir(opendir(path.c_str())); + _assert(dir != NULL); + _scope({ _syscall(closedir(dir)); }); + + while (auto child = readdir(dir)) { + std::string name(child->d_name, child->d_namlen); + if (name == "." || name == "..") + continue; + if (Starts(name, ".ldid.")) + continue; + + switch (child->d_type) { + case DT_DIR: + Find(root, base + name + "/", code); + break; + + case DT_REG: + code(base + name, fun([&](const Functor &code) { + std::string access(root + base + name); + _assert_(Open(access, fun([&](std::streambuf &data) { + NullBuffer save; + code(data, save); + })), "open(): %s", access.c_str()); + })); + break; + + default: + _assert_(false, "d_type=%u", child->d_type); + break; + } + } +} + void DiskFolder::Save(const std::string &path, const Functor &code) { std::filebuf save; auto from(Path(path)); @@ -1581,43 +1617,7 @@ bool DiskFolder::Open(const std::string &path, const Functor &)> &)>&code) { - auto root(Path(path)); - - FTS *fts(fts_open((char *[]) {const_cast(root.c_str()), NULL}, FTS_PHYSICAL | FTS_NOCHDIR, NULL)); - _assert(fts != NULL); - _scope({ fts_close(fts); }); - - while (FTSENT *entry = fts_read(fts)) { - _assert(entry->fts_pathlen >= root.size()); - _assert(strncmp(entry->fts_path, root.c_str(), root.size()) == 0); - if (entry->fts_pathlen == root.size()) - continue; - - _assert(entry->fts_path[root.size()] == '/'); - std::string name(entry->fts_path + root.size() + 1); - - if (Starts(Split(name).base, ".ldid.")) - continue; - - switch (auto info = entry->fts_info) { - case FTS_D: - case FTS_DP: - break; - - case FTS_F: { - code(name, fun([&](const Functor &code) { - std::string access(path + name); - _assert_(Open(access, fun([&](std::streambuf &data) { - NullBuffer save; - code(data, save); - })), "open(): %s", access.c_str()); - })); - } break; - - default: - _assert_(false, "fts_info=%u", info); - } - } + Find(path, "", code); } SubFolder::SubFolder(Folder *parent, const std::string &path) : diff --git a/ldid.hpp b/ldid.hpp index 4ae4950..e9a0be9 100644 --- a/ldid.hpp +++ b/ldid.hpp @@ -61,6 +61,8 @@ class DiskFolder : std::string Path(const std::string &path); + void Find(const std::string &root, const std::string &base, const Functor &)> &)>&code); + public: DiskFolder(const std::string &path); ~DiskFolder(); -- 2.45.2