aboutsummaryrefslogtreecommitdiff
path: root/zencore/filesystem.cpp
diff options
context:
space:
mode:
authorMartin Ridgers <[email protected]>2021-10-25 14:26:50 +0200
committerMartin Ridgers <[email protected]>2021-10-25 22:50:43 +0200
commit40dd0012db5716868aad6aac47ebba59ef9647ba (patch)
treeb6528e122e6ee265882838da7dcc61ecc69a608a /zencore/filesystem.cpp
parentImplemented ScanFile() on POSIX (diff)
downloadzen-40dd0012db5716868aad6aac47ebba59ef9647ba.tar.xz
zen-40dd0012db5716868aad6aac47ebba59ef9647ba.zip
CopyFile() for POSIX
Diffstat (limited to 'zencore/filesystem.cpp')
-rw-r--r--zencore/filesystem.cpp51
1 files changed, 44 insertions, 7 deletions
diff --git a/zencore/filesystem.cpp b/zencore/filesystem.cpp
index 50a82c99b..181b879db 100644
--- a/zencore/filesystem.cpp
+++ b/zencore/filesystem.cpp
@@ -418,7 +418,6 @@ CloneFile(std::filesystem::path FromPath, std::filesystem::path ToPath)
bool
CopyFile(std::filesystem::path FromPath, std::filesystem::path ToPath, const CopyFileOptions& Options)
{
-#if ZEN_PLATFORM_WINDOWS
bool Success = false;
if (Options.EnableClone)
@@ -436,6 +435,7 @@ CopyFile(std::filesystem::path FromPath, std::filesystem::path ToPath, const Cop
return false;
}
+#if ZEN_PLATFORM_WINDOWS
BOOL CancelFlag = FALSE;
Success = !!::CopyFileExW(FromPath.c_str(),
ToPath.c_str(),
@@ -443,17 +443,54 @@ CopyFile(std::filesystem::path FromPath, std::filesystem::path ToPath, const Cop
/* lpData */ nullptr,
&CancelFlag,
/* dwCopyFlags */ 0);
+#else
+ using namespace fmt::literals;
- if (!Success)
+ struct ScopedFd { ~ScopedFd() { close(Fd); } int Fd; };
+
+ // From file
+ int FromFd = open(FromPath.c_str(), O_RDONLY);
+ if (FromFd < 0)
{
- throw std::system_error(std::error_code(::GetLastError(), std::system_category()), "file copy failed");
+ ThrowLastError("failed to open file {}"_format(FromPath));
}
+ ScopedFd $From = { FromFd };
- return Success;
-#else
- ZEN_ERROR("CopyFile() is not implemented on this platform");
- return false;
+ // To file
+ int ToFd = open(ToPath.c_str(), O_WRONLY|O_CREAT|O_EXCL);
+ if (ToFd < 0)
+ {
+ ThrowLastError("failed to create file {}"_format(ToPath));
+ }
+ ScopedFd $To = { ToFd };
+
+ // Copy impl
+ static const size_t BufferSize = 64 << 10;
+ void* Buffer = malloc(BufferSize);
+ while (true)
+ {
+ int BytesRead = read(FromFd, Buffer, BufferSize);
+ if (BytesRead <= 0)
+ {
+ Success = (BytesRead == 0);
+ break;
+ }
+
+ if (write(ToFd, Buffer, BytesRead) != BufferSize)
+ {
+ Success = false;
+ break;
+ }
+ }
+ free(Buffer);
#endif // ZEN_PLATFORM_WINDOWS
+
+ if (!Success)
+ {
+ ThrowLastError("file copy failed"sv);
+ }
+
+ return true;
}
void