aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/filesystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencore/filesystem.cpp')
-rw-r--r--src/zencore/filesystem.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp
index 5716d1255..8279fb952 100644
--- a/src/zencore/filesystem.cpp
+++ b/src/zencore/filesystem.cpp
@@ -1469,6 +1469,36 @@ GetModificationTickFromHandle(void* NativeHandle, std::error_code& Ec)
return 0;
}
+uint64_t
+GetModificationTickFromPath(const std::filesystem::path& Filename)
+{
+ // PathFromHandle
+ void* Handle;
+#if ZEN_PLATFORM_WINDOWS
+ Handle = CreateFileW(Filename.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ ThrowLastError(fmt::format("Failed to open file {} to check modification tick.", Filename));
+ }
+ auto _ = MakeGuard([Handle]() { CloseHandle(Handle); });
+#else
+ int Fd = open(Filename.c_str(), O_RDONLY | O_CLOEXEC);
+ if (Fd <= 9)
+ {
+ ThrowLastError(fmt::format("Failed to open file {} to check modification tick.", Filename));
+ }
+ Handle = (void*)uintptr_t(Fd);
+ auto _ = MakeGuard([Handle]() { close(int(uintptr_t(Handle))); });
+#endif
+ std::error_code Ec;
+ uint64_t ModificatonTick = GetModificationTickFromHandle(Handle, Ec);
+ if (Ec)
+ {
+ ThrowSystemError(Ec.value(), Ec.message());
+ }
+ return ModificatonTick;
+}
+
std::filesystem::path
GetRunningExecutablePath()
{
@@ -1895,6 +1925,116 @@ PickDefaultSystemRootDirectory()
#endif // ZEN_PLATFORM_WINDOWS
}
+#if ZEN_PLATFORM_WINDOWS
+
+uint32_t
+GetFileAttributes(const std::filesystem::path& Filename)
+{
+ DWORD Attributes = ::GetFileAttributes(Filename.native().c_str());
+ if (Attributes == INVALID_FILE_ATTRIBUTES)
+ {
+ ThrowLastError(fmt::format("failed to get attributes of file {}", Filename));
+ }
+ return (uint32_t)Attributes;
+}
+
+void
+SetFileAttributes(const std::filesystem::path& Filename, uint32_t Attributes)
+{
+ if (::SetFileAttributes(Filename.native().c_str(), Attributes) == 0)
+ {
+ ThrowLastError(fmt::format("failed to set attributes of file {}", Filename));
+ }
+}
+
+#endif // ZEN_PLATFORM_WINDOWS
+
+#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+
+uint32_t
+GetFileMode(const std::filesystem::path& Filename)
+{
+ struct stat Stat;
+ int err = stat(Filename.native().c_str(), &Stat);
+ if (err)
+ {
+ ThrowLastError(fmt::format("Failed to get mode of file {}", Filename));
+ }
+ return (uint32_t)Stat.st_mode;
+}
+
+void
+SetFileMode(const std::filesystem::path& Filename, uint32_t Attributes)
+{
+ int err = chmod(Filename.native().c_str(), (mode_t)Attributes);
+ if (err)
+ {
+ ThrowLastError(fmt::format("Failed to set mode of file {}", Filename));
+ }
+}
+
+#endif // ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+
+#if ZEN_PLATFORM_WINDOWS
+const uint32_t FileAttributesSystemReadOnlyFlag = FILE_ATTRIBUTE_READONLY;
+#else
+const uint32_t FileAttributesSystemReadOnlyFlag = 0x00000001;
+#endif // ZEN_PLATFORM_WINDOWS
+
+const uint32_t FileModeWriteEnableFlags = 0222;
+
+bool
+IsFileAttributeReadOnly(uint32_t FileAttributes)
+{
+#if ZEN_PLATFORM_WINDOWS
+ return (FileAttributes & FileAttributesSystemReadOnlyFlag) != 0;
+#else
+ return (FileAttributes & 0x00000001) != 0;
+#endif // ZEN_PLATFORM_WINDOWS
+}
+
+bool
+IsFileModeReadOnly(uint32_t FileMode)
+{
+ return (FileMode & FileModeWriteEnableFlags) == 0;
+}
+
+uint32_t
+MakeFileAttributeReadOnly(uint32_t FileAttributes, bool ReadOnly)
+{
+ return ReadOnly ? (FileAttributes | FileAttributesSystemReadOnlyFlag) : (FileAttributes & ~FileAttributesSystemReadOnlyFlag);
+}
+
+uint32_t
+MakeFileModeReadOnly(uint32_t FileMode, bool ReadOnly)
+{
+ return ReadOnly ? (FileMode & ~FileModeWriteEnableFlags) : (FileMode | FileModeWriteEnableFlags);
+}
+
+bool
+SetFileReadOnly(const std::filesystem::path& Filename, bool ReadOnly)
+{
+#if ZEN_PLATFORM_WINDOWS
+ uint32_t CurrentAttributes = GetFileAttributes(Filename);
+ uint32_t NewAttributes = MakeFileAttributeReadOnly(CurrentAttributes, ReadOnly);
+ if (CurrentAttributes != NewAttributes)
+ {
+ SetFileAttributes(Filename, NewAttributes);
+ return true;
+ }
+#endif // ZEN_PLATFORM_WINDOWS
+#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+ uint32_t CurrentMode = GetFileMode(Filename);
+ uint32_t NewMode = MakeFileModeReadOnly(CurrentMode, ReadOnly);
+ if (CurrentMode != NewMode)
+ {
+ SetFileMode(Filename, NewMode);
+ return true;
+ }
+#endif // ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+ return false;
+}
+
//////////////////////////////////////////////////////////////////////////
//
// Testing related code follows...