summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Freeman (saurik) <saurik@saurik.com>2015-09-28 02:38:55 -0700
committerJay Freeman (saurik) <saurik@saurik.com>2015-09-28 02:38:55 -0700
commit54a0f854a764b94490a1ecd8cde9fbe70de6a3bb (patch)
tree2e7b837e0ac4a5ec7151c300b226ea7ac690d9a4
parent23c11ee8bcbc98bcaa3bc3682ab123f8a44d0b01 (diff)
downloadldid-54a0f854a764b94490a1ecd8cde9fbe70de6a3bb.tar.gz
ldid-54a0f854a764b94490a1ecd8cde9fbe70de6a3bb.tar.zst
ldid-54a0f854a764b94490a1ecd8cde9fbe70de6a3bb.zip
Avoid FTS (broken in glibc, not present on Win32).
-rw-r--r--ldid.cpp76
-rw-r--r--ldid.hpp2
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 <string>
#include <vector>
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#include <fts.h>
#include <regex.h>
#include <stdbool.h>
#include <stdint.h>
@@ -1563,6 +1563,42 @@ DiskFolder::~DiskFolder() {
Commit(commit.first, commit.second);
}
+void DiskFolder::Find(const std::string &root, const std::string &base, const Functor<void (const std::string &, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &)>&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<void (std::streambuf &, std::streambuf &)> &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<void (std::streambuf &)> &code) {
std::filebuf save;
auto from(Path(path));
@@ -1581,43 +1617,7 @@ bool DiskFolder::Open(const std::string &path, const Functor<void (std::streambu
}
void DiskFolder::Find(const std::string &path, const Functor<void (const std::string &, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &)>&code) {
- auto root(Path(path));
-
- FTS *fts(fts_open((char *[]) {const_cast<char *>(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<void (std::streambuf &, std::streambuf &)> &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<void (const std::string &, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &)>&code);
+
public:
DiskFolder(const std::string &path);
~DiskFolder();