From d39fdc301d85ea39abe331e59a49273626a98a6c Mon Sep 17 00:00:00 2001 From: Martin Ridgers Date: Thu, 16 Sep 2021 16:42:08 +0200 Subject: Implemented FileSysTraversal for Linux using open/read/closedir() --- zencore/filesystem.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'zencore/filesystem.cpp') diff --git a/zencore/filesystem.cpp b/zencore/filesystem.cpp index 741e3ee19..a03623196 100644 --- a/zencore/filesystem.cpp +++ b/zencore/filesystem.cpp @@ -17,6 +17,7 @@ # include # include #else +# include # include # include # include @@ -610,6 +611,7 @@ ToUtf8(const std::filesystem::path& Path) void FileSystemTraversal::TraverseFileSystem(const std::filesystem::path& RootDir, TreeVisitor& Visitor) { +#if ZEN_PLATFORM_WINDOWS uint64_t FileInfoBuffer[8 * 1024]; FILE_INFO_BY_HANDLE_CLASS FibClass = FileIdBothDirectoryRestartInfo; @@ -697,8 +699,53 @@ FileSystemTraversal::TraverseFileSystem(const std::filesystem::path& RootDir, Tr EntryOffset += NextOffset; } } +#else + using namespace fmt::literals; + + /* Could also implement this using Linux's getdents() syscall */ + + DIR* Dir = opendir(RootDir.c_str()); + if (Dir == nullptr) + { + ThrowLastError("Failed to open directory for traversal: {}"_format(RootDir.c_str())); + } + + for (struct dirent* Entry; Entry = readdir(Dir);) + { + const char* FileName = Entry->d_name; + + struct stat Stat; + std::filesystem::path FullPath = RootDir / FileName; + stat(FullPath.c_str(), &Stat); + + if (S_ISDIR(Stat.st_mode)) + { + if (strcmp(FileName, ".") == 0 || strcmp(FileName, "..") == 0) + { + /* nop */ + } + else if (Visitor.VisitDirectory(RootDir, FileName)) + { + TraverseFileSystem(FullPath, Visitor); + } + } + else if (S_ISREG(Stat.st_mode)) + { + Visitor.VisitFile(RootDir, FileName, Stat.st_size); + } + else + { + ZEN_WARN("encountered non-regular file during file system traversal ({}): {} found in {}", + Stat.st_mode, FileName, RootDir.c_str()); + } + } + + closedir(Dir); +#endif // ZEN_PLATFORM_WINDOWS } + + std::filesystem::path PathFromHandle(void* NativeHandle) { -- cgit v1.2.3