Index: libcxx/src/filesystem/filesystem_common.h =================================================================== --- libcxx/src/filesystem/filesystem_common.h +++ libcxx/src/filesystem/filesystem_common.h @@ -522,7 +522,11 @@ } }; +#if defined(_LIBCPP_WIN32API) +using fs_time = time_util; +#else using fs_time = time_util; +#endif #if defined(__APPLE__) TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } @@ -532,6 +536,7 @@ TimeSpec extract_atime(StatT const& st) { return st.st_atim; } #endif +#if !defined(_LIBCPP_WIN32API) // allow the utimes implementation to compile even it we're not going // to use it. @@ -571,6 +576,7 @@ return posix_utimensat(p, TS, ec); #endif } +#endif /* !_LIBCPP_WIN32API */ } // namespace } // end namespace detail Index: libcxx/src/filesystem/operations.cpp =================================================================== --- libcxx/src/filesystem/operations.cpp +++ libcxx/src/filesystem/operations.cpp @@ -39,7 +39,7 @@ # define _LIBCPP_FILESYSTEM_USE_FSTREAM #endif -#if !defined(CLOCK_REALTIME) +#if !defined(CLOCK_REALTIME) && !defined(_LIBCPP_WIN32API) # include // for gettimeofday and timeval #endif @@ -334,6 +334,23 @@ 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() { errno = static_cast(win_err_to_errc(GetLastError())); return -1; @@ -593,7 +610,14 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept { typedef chrono::duration __secs; -#if defined(CLOCK_REALTIME) +#if defined(_LIBCPP_WIN32API) + typedef chrono::duration __nsecs; + FILETIME time; + GetSystemTimeAsFileTime(&time); + TimeSpec tp = detail::filetime_to_timespec(time); + return time_point(__secs(tp.tv_sec) + + chrono::duration_cast(__nsecs(tp.tv_nsec))); +#elif defined(CLOCK_REALTIME) typedef chrono::duration __nsecs; struct timespec tp; if (0 != clock_gettime(CLOCK_REALTIME, &tp)) @@ -1125,6 +1149,18 @@ using detail::fs_time; ErrorHandler err("last_write_time", ec, &p); +#if defined(_LIBCPP_WIN32API) + TimeSpec ts; + if (!fs_time::convert_to_timespec(ts, new_time) || + new_time == file_time_type::min()) + return err.report(errc::value_too_large); + detail::WinHandle h(p.c_str(), FILE_WRITE_ATTRIBUTES, 0); + if (!h) + return err.report(detail::capture_last_error()); + FILETIME last_write = timespec_to_filetime(ts); + if (!SetFileTime(h, nullptr, nullptr, &last_write)) + return err.report(detail::capture_last_error()); +#else error_code m_ec; array tbuf; #if !defined(_LIBCPP_USE_UTIMENSAT) @@ -1146,6 +1182,7 @@ 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,