diff options
Diffstat (limited to 'zencore/filesystem.cpp')
| -rw-r--r-- | zencore/filesystem.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
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 <winioctl.h> # include <winnt.h> #else +# include <dirent.h> # include <fcntl.h> # include <sys/stat.h> # include <unistd.h> @@ -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) { |