diff options
| author | Martin Ridgers <[email protected]> | 2021-10-25 14:26:50 +0200 |
|---|---|---|
| committer | Martin Ridgers <[email protected]> | 2021-10-25 22:50:43 +0200 |
| commit | 40dd0012db5716868aad6aac47ebba59ef9647ba (patch) | |
| tree | b6528e122e6ee265882838da7dcc61ecc69a608a /zencore/filesystem.cpp | |
| parent | Implemented ScanFile() on POSIX (diff) | |
| download | zen-40dd0012db5716868aad6aac47ebba59ef9647ba.tar.xz zen-40dd0012db5716868aad6aac47ebba59ef9647ba.zip | |
CopyFile() for POSIX
Diffstat (limited to 'zencore/filesystem.cpp')
| -rw-r--r-- | zencore/filesystem.cpp | 51 |
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 |