diff options
author | Sebastian Holtermann <sebholt@xwmw.org> | 2019-05-21 21:36:40 (GMT) |
---|---|---|
committer | Sebastian Holtermann <sebholt@xwmw.org> | 2019-05-22 08:57:10 (GMT) |
commit | 4b45a5d5c7f9266e5ca08f6d5676759b9aac4235 (patch) | |
tree | e5f2e186a1492544eed21587aeb796ad713fbb52 | |
parent | 0bf53483295a4b7de358e8b85ad44866d89633c5 (diff) | |
download | CMake-4b45a5d5c7f9266e5ca08f6d5676759b9aac4235.zip CMake-4b45a5d5c7f9266e5ca08f6d5676759b9aac4235.tar.gz CMake-4b45a5d5c7f9266e5ca08f6d5676759b9aac4235.tar.bz2 |
cmFileTimes: New RAII based cmFileTimes class
This adds a new RAII based cmFileTimes class.
It is supposed to replace the C style cmSystemToolsFileTime interface.
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/cmFileTimes.cxx | 127 | ||||
-rw-r--r-- | Source/cmFileTimes.h | 40 | ||||
-rwxr-xr-x | bootstrap | 1 |
4 files changed, 170 insertions, 0 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 42eed4d..8483f77 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -242,6 +242,8 @@ set(SRCS cmFileTime.h cmFileTimeCache.cxx cmFileTimeCache.h + cmFileTimes.cxx + cmFileTimes.h cmFortranParserImpl.cxx cmFSPermissions.cxx cmFSPermissions.h diff --git a/Source/cmFileTimes.cxx b/Source/cmFileTimes.cxx new file mode 100644 index 0000000..fd4f679 --- /dev/null +++ b/Source/cmFileTimes.cxx @@ -0,0 +1,127 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFileTimes.h" + +#include "cmAlgorithms.h" +#include "cm_sys_stat.h" + +#include <utility> + +#if defined(_WIN32) +# include "cmSystemTools.h" +# include <windows.h> +#else +# include <utime.h> +#endif + +#if defined(_WIN32) && \ + (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__)) +# include <io.h> +#endif + +#ifdef _WIN32 +class cmFileTimes::WindowsHandle +{ +public: + WindowsHandle(HANDLE h) + : handle_(h) + { + } + ~WindowsHandle() + { + if (this->handle_ != INVALID_HANDLE_VALUE) { + CloseHandle(this->handle_); + } + } + explicit operator bool() const + { + return this->handle_ != INVALID_HANDLE_VALUE; + } + bool operator!() const { return this->handle_ == INVALID_HANDLE_VALUE; } + operator HANDLE() const { return this->handle_; } + +private: + HANDLE handle_; +}; +#endif + +class cmFileTimes::Times +{ +public: +#if defined(_WIN32) && !defined(__CYGWIN__) + FILETIME timeCreation; + FILETIME timeLastAccess; + FILETIME timeLastWrite; +#else + struct utimbuf timeBuf; +#endif +}; + +cmFileTimes::cmFileTimes() = default; +cmFileTimes::cmFileTimes(std::string const& fileName) +{ + Load(fileName); +} +cmFileTimes::~cmFileTimes() = default; + +bool cmFileTimes::Load(std::string const& fileName) +{ + std::unique_ptr<Times> ptr; + if (IsValid()) { + // Invalidate this and re-use times + ptr.swap(this->times); + } else { + ptr = cm::make_unique<Times>(); + } + +#if defined(_WIN32) && !defined(__CYGWIN__) + cmFileTimes::WindowsHandle handle = + CreateFileW(cmSystemTools::ConvertToWindowsExtendedPath(fileName).c_str(), + GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, 0); + if (!handle) { + return false; + } + if (!GetFileTime(handle, &ptr->timeCreation, &ptr->timeLastAccess, + &ptr->timeLastWrite)) { + return false; + } +#else + struct stat st; + if (stat(fileName.c_str(), &st) < 0) { + return false; + } + ptr->timeBuf.actime = st.st_atime; + ptr->timeBuf.modtime = st.st_mtime; +#endif + // Accept times + this->times = std::move(ptr); + return true; +} + +bool cmFileTimes::Store(std::string const& fileName) const +{ + if (!IsValid()) { + return false; + } + +#if defined(_WIN32) && !defined(__CYGWIN__) + cmFileTimes::WindowsHandle handle = CreateFileW( + cmSystemTools::ConvertToWindowsExtendedPath(fileName).c_str(), + FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + if (!handle) { + return false; + } + return SetFileTime(handle, &this->times->timeCreation, + &this->times->timeLastAccess, + &this->times->timeLastWrite) != 0; +#else + return utime(fileName.c_str(), &this->times->timeBuf) >= 0; +#endif +} + +bool cmFileTimes::Copy(std::string const& fromFile, std::string const& toFile) +{ + cmFileTimes fileTimes; + return (fileTimes.Load(fromFile) && fileTimes.Store(toFile)); +} diff --git a/Source/cmFileTimes.h b/Source/cmFileTimes.h new file mode 100644 index 0000000..cbf0fe2 --- /dev/null +++ b/Source/cmFileTimes.h @@ -0,0 +1,40 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmFileTimes_h +#define cmFileTimes_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <memory> // IWYU pragma: keep +#include <string> + +/** \class cmFileTimes + * \brief Loads and stores file times. + */ +class cmFileTimes +{ +public: + cmFileTimes(); + //! Calls Load() + cmFileTimes(std::string const& fileName); + ~cmFileTimes(); + + //! @return true, if file times were loaded successfully + bool IsValid() const { return (times != nullptr); } + //! Try to load the file times from @a fileName and @return IsValid() + bool Load(std::string const& fileName); + //! Stores the file times at @a fileName (if IsValid()) + bool Store(std::string const& fileName) const; + + //! Copies the file times of @a fromFile to @a toFile + static bool Copy(std::string const& fromFile, std::string const& toFile); + +private: +#ifdef _WIN32 + class WindowsHandle; +#endif + class Times; + std::unique_ptr<Times> times; +}; + +#endif @@ -306,6 +306,7 @@ CMAKE_CXX_SOURCES="\ cmFileInstaller \ cmFileTime \ cmFileTimeCache \ + cmFileTimes \ cmFindBase \ cmFindCommon \ cmFindFileCommand \ |