mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
cmFileTime: Fix overflow on time computation
On Windows, time starting point is Januray, 1st of 1601. So computing number of nanoseconds from this date exceeds 64bit capabilities.
This commit is contained in:
@@ -24,13 +24,13 @@ bool cmFileTime::Load(std::string const& fileName)
|
|||||||
}
|
}
|
||||||
# if CMake_STAT_HAS_ST_MTIM
|
# if CMake_STAT_HAS_ST_MTIM
|
||||||
// Nanosecond resolution
|
// Nanosecond resolution
|
||||||
this->NS = fst.st_mtim.tv_sec * NsPerS + fst.st_mtim.tv_nsec;
|
this->Time = fst.st_mtim.tv_sec * UtPerS + fst.st_mtim.tv_nsec;
|
||||||
# elif CMake_STAT_HAS_ST_MTIMESPEC
|
# elif CMake_STAT_HAS_ST_MTIMESPEC
|
||||||
// Nanosecond resolution
|
// Nanosecond resolution
|
||||||
this->NS = fst.st_mtimespec.tv_sec * NsPerS + fst.st_mtimespec.tv_nsec;
|
this->Time = fst.st_mtimespec.tv_sec * UtPerS + fst.st_mtimespec.tv_nsec;
|
||||||
# else
|
# else
|
||||||
// Second resolution
|
// Second resolution
|
||||||
this->NS = fst.st_mtime * NsPerS;
|
this->Time = fst.st_mtime * UtPerS;
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
// Windows version. Get the modification time from extended file attributes.
|
// Windows version. Get the modification time from extended file attributes.
|
||||||
@@ -41,10 +41,11 @@ bool cmFileTime::Load(std::string const& fileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy the file time to the output location.
|
// Copy the file time to the output location.
|
||||||
this->NS = (static_cast<NSC>(fdata.ftLastWriteTime.dwHighDateTime) << 32) |
|
using uint64 = unsigned long long;
|
||||||
static_cast<NSC>(fdata.ftLastWriteTime.dwLowDateTime);
|
|
||||||
// The file time resolution is 100 ns.
|
this->Time = static_cast<TimeType>(
|
||||||
this->NS *= 100;
|
(uint64(fdata.ftLastWriteTime.dwHighDateTime) << 32) +
|
||||||
|
fdata.ftLastWriteTime.dwLowDateTime);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -13,9 +13,15 @@
|
|||||||
class cmFileTime
|
class cmFileTime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using NSC = long long;
|
using TimeType = long long;
|
||||||
static constexpr NSC NsPerS = 1000000000;
|
// unit time per second
|
||||||
|
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
// unit time is one nanosecond
|
||||||
|
static constexpr TimeType UtPerS = 1000000000;
|
||||||
|
#else
|
||||||
|
// unit time is 100 nanosecond
|
||||||
|
static constexpr TimeType UtPerS = 10000000;
|
||||||
|
#endif
|
||||||
cmFileTime() = default;
|
cmFileTime() = default;
|
||||||
~cmFileTime() = default;
|
~cmFileTime() = default;
|
||||||
|
|
||||||
@@ -28,22 +34,28 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Return true if this is older than ftm
|
* @brief Return true if this is older than ftm
|
||||||
*/
|
*/
|
||||||
bool Older(cmFileTime const& ftm) const { return (this->NS - ftm.NS) < 0; }
|
bool Older(cmFileTime const& ftm) const
|
||||||
|
{
|
||||||
|
return (this->Time - ftm.Time) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return true if this is newer than ftm
|
* @brief Return true if this is newer than ftm
|
||||||
*/
|
*/
|
||||||
bool Newer(cmFileTime const& ftm) const { return (ftm.NS - this->NS) < 0; }
|
bool Newer(cmFileTime const& ftm) const
|
||||||
|
{
|
||||||
|
return (ftm.Time - this->Time) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return true if this is the same as ftm
|
* @brief Return true if this is the same as ftm
|
||||||
*/
|
*/
|
||||||
bool Equal(cmFileTime const& ftm) const { return this->NS == ftm.NS; }
|
bool Equal(cmFileTime const& ftm) const { return this->Time == ftm.Time; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return true if this is not the same as ftm
|
* @brief Return true if this is not the same as ftm
|
||||||
*/
|
*/
|
||||||
bool Differ(cmFileTime const& ftm) const { return this->NS != ftm.NS; }
|
bool Differ(cmFileTime const& ftm) const { return this->Time != ftm.Time; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compare file modification times.
|
* @brief Compare file modification times.
|
||||||
@@ -51,7 +63,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
int Compare(cmFileTime const& ftm) const
|
int Compare(cmFileTime const& ftm) const
|
||||||
{
|
{
|
||||||
NSC const diff = this->NS - ftm.NS;
|
TimeType const diff = this->Time - ftm.Time;
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -65,7 +77,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool OlderS(cmFileTime const& ftm) const
|
bool OlderS(cmFileTime const& ftm) const
|
||||||
{
|
{
|
||||||
return (ftm.NS - this->NS) >= cmFileTime::NsPerS;
|
return (ftm.Time - this->Time) >= cmFileTime::UtPerS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,7 +85,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool NewerS(cmFileTime const& ftm) const
|
bool NewerS(cmFileTime const& ftm) const
|
||||||
{
|
{
|
||||||
return (this->NS - ftm.NS) >= cmFileTime::NsPerS;
|
return (this->Time - ftm.Time) >= cmFileTime::UtPerS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,11 +93,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool EqualS(cmFileTime const& ftm) const
|
bool EqualS(cmFileTime const& ftm) const
|
||||||
{
|
{
|
||||||
NSC diff = this->NS - ftm.NS;
|
TimeType diff = this->Time - ftm.Time;
|
||||||
if (diff < 0) {
|
if (diff < 0) {
|
||||||
diff = -diff;
|
diff = -diff;
|
||||||
}
|
}
|
||||||
return (diff < cmFileTime::NsPerS);
|
return (diff < cmFileTime::UtPerS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,11 +105,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool DifferS(cmFileTime const& ftm) const
|
bool DifferS(cmFileTime const& ftm) const
|
||||||
{
|
{
|
||||||
NSC diff = this->NS - ftm.NS;
|
TimeType diff = this->Time - ftm.Time;
|
||||||
if (diff < 0) {
|
if (diff < 0) {
|
||||||
diff = -diff;
|
diff = -diff;
|
||||||
}
|
}
|
||||||
return (diff >= cmFileTime::NsPerS);
|
return (diff >= cmFileTime::UtPerS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,21 +119,21 @@ public:
|
|||||||
*/
|
*/
|
||||||
int CompareS(cmFileTime const& ftm) const
|
int CompareS(cmFileTime const& ftm) const
|
||||||
{
|
{
|
||||||
NSC const diff = this->NS - ftm.NS;
|
TimeType const diff = this->Time - ftm.Time;
|
||||||
if (diff <= -cmFileTime::NsPerS) {
|
if (diff <= -cmFileTime::UtPerS) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (diff >= cmFileTime::NsPerS) {
|
if (diff >= cmFileTime::UtPerS) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The file modification time in nanoseconds
|
* @brief The file modification time in unit time per second
|
||||||
*/
|
*/
|
||||||
NSC GetNS() const { return this->NS; }
|
TimeType GetTime() const { return this->Time; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NSC NS = 0;
|
TimeType Time = 0;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user