This fixes linking against a DLL of libc++ while using the common headers (generated from the static version of the library, but which work for both shared and static versions) when calling e.g. std::filesystem::u8path.
134 lines
4.6 KiB
Diff
134 lines
4.6 KiB
Diff
From ab432bcd28596265e97eb062a19cbbbdc3d426f5 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
|
|
Date: Wed, 4 Nov 2020 22:56:03 +0200
|
|
Subject: [PATCH 02/25] [libcxx] Implement _FilesystemClock::now() and
|
|
__last_write_time for windows
|
|
|
|
Differential Revision: https://reviews.llvm.org/D91142
|
|
|
|
(cherry picked from commit 592d62352933d34af62334d172c6fc665933e0de)
|
|
---
|
|
libcxx/src/filesystem/filesystem_common.h | 6 ++++++
|
|
libcxx/src/filesystem/operations.cpp | 23 +++++++++++++++++++++--
|
|
libcxx/src/filesystem/posix_compat.h | 17 +++++++++++++++++
|
|
3 files changed, 44 insertions(+), 2 deletions(-)
|
|
|
|
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 @@ public:
|
|
}
|
|
};
|
|
|
|
+#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;
|
|
--
|
|
2.25.1
|
|
|