summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Holtermann <sebholt@xwmw.org>2019-05-21 21:36:40 (GMT)
committerSebastian Holtermann <sebholt@xwmw.org>2019-05-22 08:57:10 (GMT)
commit4b45a5d5c7f9266e5ca08f6d5676759b9aac4235 (patch)
treee5f2e186a1492544eed21587aeb796ad713fbb52
parent0bf53483295a4b7de358e8b85ad44866d89633c5 (diff)
downloadCMake-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.txt2
-rw-r--r--Source/cmFileTimes.cxx127
-rw-r--r--Source/cmFileTimes.h40
-rwxr-xr-xbootstrap1
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
diff --git a/bootstrap b/bootstrap
index c5274ce..95d25b6 100755
--- a/bootstrap
+++ b/bootstrap
@@ -306,6 +306,7 @@ CMAKE_CXX_SOURCES="\
cmFileInstaller \
cmFileTime \
cmFileTimeCache \
+ cmFileTimes \
cmFindBase \
cmFindCommon \
cmFindFileCommand \