diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp @@ -28,7 +28,9 @@ #include "filesystem_test_helper.h" #include +#ifndef _WIN32 #include +#endif #include using namespace fs; @@ -39,6 +41,7 @@ using Sec = std::chrono::duration; using Hours = std::chrono::hours; using Minutes = std::chrono::minutes; +using MilliSec = std::chrono::duration; using MicroSec = std::chrono::duration; using NanoSec = std::chrono::duration; using std::chrono::duration_cast; @@ -46,6 +49,9 @@ #if defined(__APPLE__) TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } +#elif defined(_WIN32) +TimeSpec extract_mtime(StatT const& st) { return TimeSpec{st.st_mtime, 0}; } +TimeSpec extract_atime(StatT const& st) { return TimeSpec{st.st_atime, 0}; } #else TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } TimeSpec extract_atime(StatT const& st) { return st.st_atim; } @@ -122,6 +128,8 @@ TimeSpec LastWriteTime(path const& p) { return GetTimes(p).write; } +#ifndef _WIN32 +// There's no lstat() in the Windows CRTs Times GetSymlinkTimes(path const& p) { StatT st; if (::lstat(p.string().c_str(), &st) == -1) { @@ -137,6 +145,7 @@ res.write = extract_mtime(st); return res; } +#endif namespace { @@ -250,6 +259,12 @@ } // end namespace static bool CompareTime(TimeSpec t1, TimeSpec t2) { +#ifdef _WIN32 + // Windows does support file times with a 100 ns unit, but this test + // only uses the CRT stat() to inspect the tested files, and stat() only + // returns times with second granularity. + return t1.tv_sec == t2.tv_sec; +#else if (SupportsNanosecondRoundTrip) return CompareTimeExact(t1, t2); if (t1.tv_sec != t2.tv_sec) @@ -259,6 +274,7 @@ if (WorkaroundStatTruncatesToSeconds) return diff < duration_cast(Sec(1)).count(); return diff < duration_cast(MicroSec(1)).count(); +#endif } static bool CompareTime(file_time_type t1, TimeSpec t2) { @@ -349,6 +365,11 @@ static_test_env static_env; using C = file_time_type::clock; file_time_type min = file_time_type::min(); + // Sleep a little to make sure that static_env.File created above is + // strictly older than C::now() even with a coarser clock granularity + // in C::now(). (GetSystemTimeAsFileTime on windows has a fairly coarse + // granularity.) + SleepFor(MilliSec(30)); { file_time_type ret = last_write_time(static_env.File); TEST_CHECK(ret != min); @@ -471,6 +492,8 @@ } } +#ifndef _WIN32 +// There's no lstat() in the Windows CRTs TEST_CASE(last_write_time_symlink_test) { using Clock = file_time_type::clock; @@ -502,6 +525,7 @@ Times sym_times = GetSymlinkTimes(sym); TEST_CHECK(CompareTime(sym_times.write, old_sym_times.write)); } +#endif TEST_CASE(test_write_min_time) diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h --- a/libcxx/test/support/filesystem_test_helper.h +++ b/libcxx/test/support/filesystem_test_helper.h @@ -575,7 +575,8 @@ // Provide our own Sleep routine since std::this_thread::sleep_for is not // available in single-threaded mode. -void SleepFor(std::chrono::seconds dur) { +template +void SleepFor(Dur dur) { using namespace std::chrono; #if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) using Clock = system_clock;