diff options
author | Laszlo Csomor <laszlocsomor@google.com> | 2018-06-13 08:33:28 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-06-13 08:34:35 -0700 |
commit | 6b43357f76154838df7bfd838a844cf96afc2af9 (patch) | |
tree | a20712fd1a28ab543561b0cbdf105433d22d1020 /src/main/cpp | |
parent | b5daae329c66e6e7cff7db33a451165b56f8f9ee (diff) |
Windows: fix "corrupt installation" at new year
Bazel on Windows is now consistent with Bazel on
Unixes, by setting the mtimes of embedded binaries
to 10 years in the future.
Before this change, on Windows, Bazel used to set
these mtimes to CURRENT_YEAR + 10, January 1st.
This meant that if a user ran Bazel on 2017/12/29,
then on Unix Bazel set the mtimes to 2027/12/29
but on Windows it set them to 2027/01/01.
If the user then ran Bazel in the same workspace
on 2018/01/02, on Unixes it worked fine, but on
Windows it detected that the embedded binaries'
mtime is older than 2018/01/01, and reported a
"corrupt installation" error.
Fixes https://github.com/bazelbuild/bazel/issues/4378
Change-Id: I3457bdc360a62a279d1d08c9a69997929f2067dd
Closes #5385.
Change-Id: I3457bdc360a62a279d1d08c9a69997929f2067dd
PiperOrigin-RevId: 200395493
Diffstat (limited to 'src/main/cpp')
-rw-r--r-- | src/main/cpp/util/file_windows.cc | 94 |
1 files changed, 62 insertions, 32 deletions
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc index 537852eb70..ee045a3718 100644 --- a/src/main/cpp/util/file_windows.cc +++ b/src/main/cpp/util/file_windows.cc @@ -114,16 +114,59 @@ class WindowsFileMtime : public IFileMtime { bool SetToDistantFuture(const string& path) override; private: + // 1 year in FILETIME. + static const ULARGE_INTEGER kOneYear; // 9 years in the future. const FILETIME near_future_; // 10 years in the future. const FILETIME distant_future_; - static FILETIME GetNow(); - static FILETIME GetFuture(WORD years); + static ULARGE_INTEGER&& OneYearDelay(); + static const FILETIME GetNow(); + static const FILETIME GetFuture(WORD years); static bool Set(const string& path, const FILETIME& time); }; +const ULARGE_INTEGER WindowsFileMtime::kOneYear = + std::move(WindowsFileMtime::OneYearDelay()); + +ULARGE_INTEGER&& WindowsFileMtime::OneYearDelay() { + SYSTEMTIME now; + GetSystemTime(&now); + now.wMonth = 1; + now.wDayOfWeek = 0; + now.wDay = 1; + now.wHour = 0; + now.wMinute = 0; + now.wSecond = 0; + now.wMilliseconds = 0; + + FILETIME now_ft; + if (!::SystemTimeToFileTime(&now, &now_ft)) { + string err = GetLastErrorString(); + BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR) + << "WindowsFileMtime::OneYearDelay: SystemTimeToFileTime 1 failed: " + << err; + } + ULARGE_INTEGER t1; + t1.LowPart = now_ft.dwLowDateTime; + t1.HighPart = now_ft.dwHighDateTime; + + now.wYear++; + if (!::SystemTimeToFileTime(&now, &now_ft)) { + string err = GetLastErrorString(); + BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR) + << "WindowsFileMtime::OneYearDelay: SystemTimeToFileTime 2 failed: " + << err; + } + ULARGE_INTEGER t2; + t2.LowPart = now_ft.dwLowDateTime; + t2.HighPart = now_ft.dwHighDateTime; + + t2.QuadPart -= t1.QuadPart; + return std::move(t2); +} + bool WindowsFileMtime::GetIfInDistantFuture(const string& path, bool* result) { if (path.empty()) { return false; @@ -215,36 +258,23 @@ bool WindowsFileMtime::Set(const string& path, const FILETIME& time) { /* lpLastWriteTime */ &time) == TRUE; } -FILETIME WindowsFileMtime::GetNow() { - SYSTEMTIME sys_time; - ::GetSystemTime(&sys_time); - FILETIME file_time; - if (!::SystemTimeToFileTime(&sys_time, &file_time)) { - BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR) - << "WindowsFileMtime::GetNow: SystemTimeToFileTime failed: " - << GetLastErrorString(); - } - return file_time; -} - -FILETIME WindowsFileMtime::GetFuture(WORD years) { - SYSTEMTIME future_time; - GetSystemTime(&future_time); - future_time.wYear += years; - future_time.wMonth = 1; - future_time.wDayOfWeek = 0; - future_time.wDay = 1; - future_time.wHour = 0; - future_time.wMinute = 0; - future_time.wSecond = 0; - future_time.wMilliseconds = 0; - FILETIME file_time; - if (!::SystemTimeToFileTime(&future_time, &file_time)) { - BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR) - << "WindowsFileMtime::GetFuture: SystemTimeToFileTime failed: " - << GetLastErrorString(); - } - return file_time; +const FILETIME WindowsFileMtime::GetNow() { + FILETIME now; + GetSystemTimeAsFileTime(&now); + return now; +} + +const FILETIME WindowsFileMtime::GetFuture(WORD years) { + FILETIME result; + GetSystemTimeAsFileTime(&result); + + ULARGE_INTEGER result_value; + result_value.LowPart = result.dwLowDateTime; + result_value.HighPart = result.dwHighDateTime; + result_value.QuadPart += kOneYear.QuadPart * years; + result.dwLowDateTime = result_value.LowPart; + result.dwHighDateTime = result_value.HighPart; + return result; } IFileMtime* CreateFileMtime() { return new WindowsFileMtime(); } |