From 2868ebac0f00af36a92a56bfbdf67e3555ed544e Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Thu, 3 Jul 2025 19:32:36 +0300 Subject: [PATCH] _fixup --- .../Engine/Platform/Apple/AppleFileSystem.cpp | 59 +++++++++++++++ .../Engine/Platform/Apple/AppleFileSystem.h | 1 + .../Engine/Platform/Linux/LinuxFileSystem.cpp | 72 +++++++++++++++++++ .../Engine/Platform/Linux/LinuxFileSystem.h | 1 + 4 files changed, 133 insertions(+) diff --git a/Source/Engine/Platform/Apple/AppleFileSystem.cpp b/Source/Engine/Platform/Apple/AppleFileSystem.cpp index 0f6d8084f..5cccbe3d8 100644 --- a/Source/Engine/Platform/Apple/AppleFileSystem.cpp +++ b/Source/Engine/Platform/Apple/AppleFileSystem.cpp @@ -22,6 +22,65 @@ #include #include +bool AppleFileSystem::CopyFile(const StringView& dst, const StringView& src) +{ + const StringAsANSI<> srcANSI(*src, src.Length()); + const StringAsANSI<> dstANSI(*dst, dst.Length()); + + int srcFile, dstFile; + char buffer[4096]; + ssize_t readSize; + int cachedError; + + srcFile = open(srcANSI.Get(), O_RDONLY); + if (srcFile < 0) + return true; + dstFile = open(dstANSI.Get(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (dstFile < 0) + goto out_error; + + while (readSize = read(srcFile, buffer, sizeof(buffer)), readSize > 0) + { + char* ptr = buffer; + ssize_t writeSize; + + do + { + writeSize = write(dstFile, ptr, readSize); + if (writeSize >= 0) + { + readSize -= writeSize; + ptr += writeSize; + } + else if (errno != EINTR) + { + goto out_error; + } + } while (readSize > 0); + } + + if (readSize == 0) + { + if (close(dstFile) < 0) + { + dstFile = -1; + goto out_error; + } + close(srcFile); + + // Success + return false; + } + + out_error: + cachedError = errno; + close(srcFile); + if (dstFile >= 0) + close(dstFile); + errno = cachedError; + return true; +} + void AppleFileSystem::GetSpecialFolderPath(const SpecialFolder type, String& result) { String home; diff --git a/Source/Engine/Platform/Apple/AppleFileSystem.h b/Source/Engine/Platform/Apple/AppleFileSystem.h index cf4c38a97..45d9e4df6 100644 --- a/Source/Engine/Platform/Apple/AppleFileSystem.h +++ b/Source/Engine/Platform/Apple/AppleFileSystem.h @@ -13,6 +13,7 @@ class FLAXENGINE_API AppleFileSystem : public UnixFileSystem { public: // [FileSystemBase] + static bool CopyFile(const StringView& dst, const StringView& src); static void GetSpecialFolderPath(const SpecialFolder type, String& result); }; diff --git a/Source/Engine/Platform/Linux/LinuxFileSystem.cpp b/Source/Engine/Platform/Linux/LinuxFileSystem.cpp index d87b9674f..4452068c7 100644 --- a/Source/Engine/Platform/Linux/LinuxFileSystem.cpp +++ b/Source/Engine/Platform/Linux/LinuxFileSystem.cpp @@ -165,6 +165,78 @@ bool LinuxFileSystem::ShowFileExplorer(const StringView& path) return false; } +bool LinuxFileSystem::CopyFile(const StringView& dst, const StringView& src) +{ + const StringAsUTF8<> srcANSI(*src, src.Length()); + const StringAsUTF8<> dstANSI(*dst, dst.Length()); + + int srcFile, dstFile; + char buffer[4096]; + ssize_t readSize; + int cachedError; + + srcFile = open(srcANSI.Get(), O_RDONLY); + if (srcFile < 0) + return true; + dstFile = open(dstANSI.Get(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (dstFile < 0) + goto out_error; + + // first try the kernel method + struct stat statBuf; + fstat(srcFile, &statBuf); + readSize = 1; + while (readSize > 0) + { + readSize = sendfile(dstFile, srcFile, 0, statBuf.st_size); + } + // sendfile could fail for example if the input file is not nmap'able + // in this case we fall back to the read/write loop + if (readSize < 0) + { + while (readSize = read(srcFile, buffer, sizeof(buffer)), readSize > 0) + { + char* ptr = buffer; + ssize_t writeSize; + + do + { + writeSize = write(dstFile, ptr, readSize); + if (writeSize >= 0) + { + readSize -= writeSize; + ptr += writeSize; + } + else if (errno != EINTR) + { + goto out_error; + } + } while (readSize > 0); + } + } + + if (readSize == 0) + { + if (close(dstFile) < 0) + { + dstFile = -1; + goto out_error; + } + close(srcFile); + + // Success + return false; + } + + out_error: + cachedError = errno; + close(srcFile); + if (dstFile >= 0) + close(dstFile); + errno = cachedError; + return true; +} + bool LinuxFileSystem::MoveFileToRecycleBin(const StringView& path) { String trashDir; diff --git a/Source/Engine/Platform/Linux/LinuxFileSystem.h b/Source/Engine/Platform/Linux/LinuxFileSystem.h index e96ea924c..377bbbd99 100644 --- a/Source/Engine/Platform/Linux/LinuxFileSystem.h +++ b/Source/Engine/Platform/Linux/LinuxFileSystem.h @@ -16,6 +16,7 @@ public: static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array& filenames); static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path); static bool ShowFileExplorer(const StringView& path); + static bool CopyFile(const StringView& dst, const StringView& src); static bool MoveFileToRecycleBin(const StringView& path); static void GetSpecialFolderPath(const SpecialFolder type, String& result);