Improve file time precision checks and initialize directory_entry's _last_write_time

This commit is contained in:
Steffen Schümann 2026-07-12 14:53:28 +02:00
parent 4bc18b0955
commit 16e1157d4e
2 changed files with 7 additions and 4 deletions

View File

@ -805,7 +805,10 @@ class GHC_FS_API_CLASS directory_entry
{ {
public: public:
// [fs.dir.entry.cons] constructors and destructor // [fs.dir.entry.cons] constructors and destructor
directory_entry() noexcept = default; directory_entry() noexcept
: _last_write_time((file_time_type::min)())
{
}
directory_entry(const directory_entry&) = default; directory_entry(const directory_entry&) = default;
directory_entry(directory_entry&&) noexcept = default; directory_entry(directory_entry&&) noexcept = default;
#ifdef GHC_WITH_EXCEPTIONS #ifdef GHC_WITH_EXCEPTIONS
@ -4687,7 +4690,7 @@ GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::err
#ifdef GHC_OS_WINDOWS #ifdef GHC_OS_WINDOWS
detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)); detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL));
FILETIME ft; FILETIME ft;
auto tt = std::chrono::duration_cast<std::chrono::microseconds>(d).count() * 10 + 116444736000000000; const auto tt = std::chrono::duration_cast<std::chrono::duration<int64_t, std::ratio<1, 10000000>>>(d).count() + 116444736000000000LL;
ft.dwLowDateTime = static_cast<DWORD>(tt); ft.dwLowDateTime = static_cast<DWORD>(tt);
ft.dwHighDateTime = static_cast<DWORD>(tt >> 32); ft.dwHighDateTime = static_cast<DWORD>(tt >> 32);
if (!::SetFileTime(file.get(), 0, 0, &ft)) { if (!::SetFileTime(file.get(), 0, 0, &ft)) {

View File

@ -2574,9 +2574,9 @@ TEST_CASE("fs.op.last_write_time - last_write_time", "[filesystem][operations][f
const auto preciseTime = nt + std::chrono::milliseconds(123); const auto preciseTime = nt + std::chrono::milliseconds(123);
CHECK_NOTHROW(fs::last_write_time("foo", preciseTime, ec)); CHECK_NOTHROW(fs::last_write_time("foo", preciseTime, ec));
REQUIRE(!ec); REQUIRE(!ec);
CHECK(fs::last_write_time("foo") == preciseTime); CHECK(std::abs(std::chrono::duration_cast<std::chrono::nanoseconds>(fs::last_write_time("foo") - preciseTime).count()) < 1000000);
const fs::directory_entry preciseEntry("foo"); const fs::directory_entry preciseEntry("foo");
CHECK(preciseEntry.last_write_time() == preciseTime); CHECK(std::abs(std::chrono::duration_cast<std::chrono::nanoseconds>(preciseEntry.last_write_time() - preciseTime).count()) < 1000000);
if (is_symlink_creation_supported()) { if (is_symlink_creation_supported()) {
#if !defined(GHC_OS_WINDOWS) && !defined(GHC_OS_WEB) #if !defined(GHC_OS_WINDOWS) && !defined(GHC_OS_WEB)
struct ::stat linkStatBefore; struct ::stat linkStatBefore;