[libcxx-commits] [libcxx] 592d623 - [libcxx] Implement _FilesystemClock::now() and __last_write_time for windows

Martin Storsjö via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 29 03:39:59 PST 2021


Author: Martin Storsjö
Date: 2021-01-29T13:38:27+02:00
New Revision: 592d62352933d34af62334d172c6fc665933e0de

URL: https://github.com/llvm/llvm-project/commit/592d62352933d34af62334d172c6fc665933e0de
DIFF: https://github.com/llvm/llvm-project/commit/592d62352933d34af62334d172c6fc665933e0de.diff

LOG: [libcxx] Implement _FilesystemClock::now() and __last_write_time for windows

Differential Revision: https://reviews.llvm.org/D91142

Added: 
    

Modified: 
    libcxx/src/filesystem/filesystem_common.h
    libcxx/src/filesystem/operations.cpp
    libcxx/src/filesystem/posix_compat.h

Removed: 
    


################################################################################
diff  --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h
index 8204e9a2e5f8..a4505171c3eb 100644
--- a/libcxx/src/filesystem/filesystem_common.h
+++ b/libcxx/src/filesystem/filesystem_common.h
@@ -437,7 +437,11 @@ struct time_util : time_util_base<FileTimeT, TimeT> {
   }
 };
 
+#if defined(_LIBCPP_WIN32API)
+using fs_time = time_util<file_time_type, int64_t, TimeSpec>;
+#else
 using fs_time = time_util<file_time_type, time_t, TimeSpec>;
+#endif
 
 #if defined(__APPLE__)
 inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
@@ -456,6 +460,7 @@ inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
 inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
 #endif
 
+#if !defined(_LIBCPP_WIN32API)
 inline TimeVal make_timeval(TimeSpec const& ts) {
   using namespace chrono;
   auto Convert = [](long nsec) {
@@ -498,6 +503,7 @@ bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
   return posix_utimensat(p, TS, ec);
 #endif
 }
+#endif /* !_LIBCPP_WIN32API */
 
 } // namespace
 } // end namespace detail

diff  --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index 548a0273ce71..40a863db69a1 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -42,7 +42,7 @@
 # define _LIBCPP_FILESYSTEM_USE_FSTREAM
 #endif
 
-#if !defined(CLOCK_REALTIME)
+#if !defined(CLOCK_REALTIME) && !defined(_LIBCPP_WIN32API)
 # include <sys/time.h> // for gettimeofday and timeval
 #endif
 
@@ -567,7 +567,14 @@ const bool _FilesystemClock::is_steady;
 
 _FilesystemClock::time_point _FilesystemClock::now() noexcept {
   typedef chrono::duration<rep> __secs;
-#if defined(CLOCK_REALTIME)
+#if defined(_LIBCPP_WIN32API)
+  typedef chrono::duration<rep, nano> __nsecs;
+  FILETIME time;
+  GetSystemTimeAsFileTime(&time);
+  TimeSpec tp = detail::filetime_to_timespec(time);
+  return time_point(__secs(tp.tv_sec) +
+                    chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
+#elif defined(CLOCK_REALTIME)
   typedef chrono::duration<rep, nano> __nsecs;
   struct timespec tp;
   if (0 != clock_gettime(CLOCK_REALTIME, &tp))
@@ -1121,6 +1128,17 @@ void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
   using detail::fs_time;
   ErrorHandler<void> err("last_write_time", ec, &p);
 
+#if defined(_LIBCPP_WIN32API)
+  TimeSpec ts;
+  if (!fs_time::convert_to_timespec(ts, new_time))
+    return err.report(errc::value_too_large);
+  detail::WinHandle h(p.c_str(), FILE_WRITE_ATTRIBUTES, 0);
+  if (!h)
+    return err.report(detail::make_windows_error(GetLastError()));
+  FILETIME last_write = timespec_to_filetime(ts);
+  if (!SetFileTime(h, nullptr, nullptr, &last_write))
+    return err.report(detail::make_windows_error(GetLastError()));
+#else
   error_code m_ec;
   array<TimeSpec, 2> tbuf;
 #if !defined(_LIBCPP_USE_UTIMENSAT)
@@ -1142,6 +1160,7 @@ void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
   detail::set_file_times(p, tbuf, m_ec);
   if (m_ec)
     return err.report(m_ec);
+#endif
 }
 
 void __permissions(const path& p, perms prms, perm_options opts,

diff  --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h
index 3eec4634e929..7caf9d28b49d 100644
--- a/libcxx/src/filesystem/posix_compat.h
+++ b/libcxx/src/filesystem/posix_compat.h
@@ -94,6 +94,23 @@ TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
   return ret;
 }
 
+TimeSpec filetime_to_timespec(FILETIME ft) {
+  LARGE_INTEGER li;
+  li.LowPart = ft.dwLowDateTime;
+  li.HighPart = ft.dwHighDateTime;
+  return filetime_to_timespec(li);
+}
+
+FILETIME timespec_to_filetime(TimeSpec ts) {
+  LARGE_INTEGER li;
+  li.QuadPart =
+      ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
+  FILETIME ft;
+  ft.dwLowDateTime = li.LowPart;
+  ft.dwHighDateTime = li.HighPart;
+  return ft;
+}
+
 int set_errno(int e = GetLastError()) {
   errno = static_cast<int>(__win_err_to_errc(e));
   return -1;


        


More information about the libcxx-commits mailing list