1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmFileTimes.h"
9 #include "cm_sys_stat.h"
14 # include "cmSystemTools.h"
19 #if defined(_WIN32) && \
20 (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__))
25 class cmFileTimes::WindowsHandle
28 WindowsHandle(HANDLE h)
34 if (this->handle_ != INVALID_HANDLE_VALUE) {
35 CloseHandle(this->handle_);
38 explicit operator bool() const
40 return this->handle_ != INVALID_HANDLE_VALUE;
42 bool operator!() const { return this->handle_ == INVALID_HANDLE_VALUE; }
43 operator HANDLE() const { return this->handle_; }
50 class cmFileTimes::Times
53 #if defined(_WIN32) && !defined(__CYGWIN__)
54 FILETIME timeCreation;
55 FILETIME timeLastAccess;
56 FILETIME timeLastWrite;
58 struct utimbuf timeBuf;
62 cmFileTimes::cmFileTimes() = default;
63 cmFileTimes::cmFileTimes(std::string const& fileName)
67 cmFileTimes::~cmFileTimes() = default;
69 bool cmFileTimes::Load(std::string const& fileName)
71 std::unique_ptr<Times> ptr;
72 if (this->IsValid()) {
73 // Invalidate this and re-use times
74 ptr.swap(this->times);
76 ptr = cm::make_unique<Times>();
79 #if defined(_WIN32) && !defined(__CYGWIN__)
80 cmFileTimes::WindowsHandle handle =
81 CreateFileW(cmSystemTools::ConvertToWindowsExtendedPath(fileName).c_str(),
82 GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
83 FILE_FLAG_BACKUP_SEMANTICS, 0);
87 if (!GetFileTime(handle, &ptr->timeCreation, &ptr->timeLastAccess,
88 &ptr->timeLastWrite)) {
93 if (stat(fileName.c_str(), &st) < 0) {
96 ptr->timeBuf.actime = st.st_atime;
97 ptr->timeBuf.modtime = st.st_mtime;
100 this->times = std::move(ptr);
104 bool cmFileTimes::Store(std::string const& fileName) const
106 if (!this->IsValid()) {
110 #if defined(_WIN32) && !defined(__CYGWIN__)
111 cmFileTimes::WindowsHandle handle = CreateFileW(
112 cmSystemTools::ConvertToWindowsExtendedPath(fileName).c_str(),
113 FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
117 return SetFileTime(handle, &this->times->timeCreation,
118 &this->times->timeLastAccess,
119 &this->times->timeLastWrite) != 0;
121 return utime(fileName.c_str(), &this->times->timeBuf) >= 0;
125 bool cmFileTimes::Copy(std::string const& fromFile, std::string const& toFile)
127 cmFileTimes fileTimes;
128 return (fileTimes.Load(fromFile) && fileTimes.Store(toFile));