From 100016e9cb31aad7b642a9733409c7294cd6652f Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 4 Mar 2021 11:51:03 -0500 Subject: cmSystemTools: add utilities to copy a file with error handling --- Source/cmSystemTools.cxx | 46 ++++++++++++++++++++++++++++++++++++++++++++++ Source/cmSystemTools.h | 18 ++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index db5b1ac..87ba152 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -87,6 +87,7 @@ # include # include +# include #endif #if defined(_WIN32) && \ @@ -990,6 +991,51 @@ bool cmMoveFile(std::wstring const& oldname, std::wstring const& newname, } #endif +bool cmSystemTools::CopySingleFile(const std::string& oldname, + const std::string& newname) +{ + return cmSystemTools::CopySingleFile(oldname, newname, CopyWhen::Always) == + CopyResult::Success; +} + +cmSystemTools::CopyResult cmSystemTools::CopySingleFile( + std::string const& oldname, std::string const& newname, CopyWhen when, + std::string* err) +{ + switch (when) { + case CopyWhen::Always: + break; + case CopyWhen::OnlyIfDifferent: + if (!FilesDiffer(oldname, newname)) { + return CopyResult::Success; + } + break; + } + + mode_t perm = 0; + bool perms = SystemTools::GetPermissions(oldname, perm); + + // If files are the same do not copy + if (SystemTools::SameFile(oldname, newname)) { + return CopyResult::Success; + } + + if (!cmsys::SystemTools::CloneFileContent(oldname, newname)) { + // if cloning did not succeed, fall back to blockwise copy + if (!cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname)) { + ReportError(err); + return CopyResult::Failure; + } + } + if (perms) { + if (!SystemTools::SetPermissions(newname, perm)) { + ReportError(err); + return CopyResult::Failure; + } + } + return CopyResult::Success; +} + bool cmSystemTools::RenameFile(const std::string& oldname, const std::string& newname) { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 3cc032c..2ff4c5d 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -128,6 +128,24 @@ public: static bool SimpleGlob(const std::string& glob, std::vector& files, int type = 0); + enum class CopyWhen + { + Always, + OnlyIfDifferent, + }; + enum class CopyResult + { + Success, + Failure, + }; + + /** Copy a file. */ + static bool CopySingleFile(const std::string& oldname, + const std::string& newname); + static CopyResult CopySingleFile(std::string const& oldname, + std::string const& newname, CopyWhen when, + std::string* err = nullptr); + enum class Replace { Yes, -- cgit v0.12