mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-01 09:24:55 +02:00
enh(File): Linux, macOS: microsecond precision for file times (create and modification time).
This commit is contained in:
parent
d5a5ebc2d7
commit
6456d03df7
@ -135,7 +135,7 @@ public:
|
|||||||
/// (100 nanosecond intervals since midnight,
|
/// (100 nanosecond intervals since midnight,
|
||||||
/// October 15, 1582).
|
/// October 15, 1582).
|
||||||
|
|
||||||
static TimeDiff resolution();
|
static constexpr TimeDiff resolution();
|
||||||
/// Returns the resolution in units per second.
|
/// Returns the resolution in units per second.
|
||||||
/// Since the timestamp has microsecond resolution,
|
/// Since the timestamp has microsecond resolution,
|
||||||
/// the returned value is always 1000000.
|
/// the returned value is always 1000000.
|
||||||
@ -254,7 +254,7 @@ inline bool Timestamp::isElapsed(Timestamp::TimeDiff interval) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Timestamp::TimeDiff Timestamp::resolution()
|
inline constexpr Timestamp::TimeDiff Timestamp::resolution()
|
||||||
{
|
{
|
||||||
return 1000000;
|
return 1000000;
|
||||||
}
|
}
|
||||||
|
@ -212,15 +212,24 @@ Timestamp FileImpl::createdImpl() const
|
|||||||
{
|
{
|
||||||
poco_assert (!_path.empty());
|
poco_assert (!_path.empty());
|
||||||
|
|
||||||
|
using TV = Timestamp::TimeVal;
|
||||||
|
|
||||||
|
// Nanosecond to timestamp resolution factor
|
||||||
|
static constexpr TV nsk = 1'000'000'000ll / Timestamp::resolution();
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (::stat(_path.c_str(), &st) == 0)
|
||||||
|
{
|
||||||
#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(_DARWIN_FEATURE_64_BIT_INODE))
|
#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(_DARWIN_FEATURE_64_BIT_INODE))
|
||||||
struct stat st;
|
const TV tv = static_cast<TV>(st.st_birthtimespec.tv_sec) * Timestamp::resolution() + st.st_birthtimespec.tv_nsec/nsk;
|
||||||
if (stat(_path.c_str(), &st) == 0)
|
return Timestamp(tv);
|
||||||
return Timestamp::fromEpochTime(st.st_birthtime);
|
#elif POCO_OS == POCO_OS_LINUX
|
||||||
|
const TV tv = static_cast<TV>(st.st_ctim.tv_sec) * Timestamp::resolution() + st.st_ctim.tv_nsec/nsk;
|
||||||
|
return Timestamp(tv);
|
||||||
#else
|
#else
|
||||||
struct stat st;
|
|
||||||
if (stat(_path.c_str(), &st) == 0)
|
|
||||||
return Timestamp::fromEpochTime(st.st_ctime);
|
return Timestamp::fromEpochTime(st.st_ctime);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
handleLastErrorImpl(_path);
|
handleLastErrorImpl(_path);
|
||||||
return 0;
|
return 0;
|
||||||
@ -231,9 +240,24 @@ Timestamp FileImpl::getLastModifiedImpl() const
|
|||||||
{
|
{
|
||||||
poco_assert (!_path.empty());
|
poco_assert (!_path.empty());
|
||||||
|
|
||||||
|
using TV = Timestamp::TimeVal;
|
||||||
|
|
||||||
|
// Nanosecond to timestamp resolution factor
|
||||||
|
static constexpr TV nsk = 1'000'000'000ll / Timestamp::resolution();
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(_path.c_str(), &st) == 0)
|
if (::stat(_path.c_str(), &st) == 0)
|
||||||
|
{
|
||||||
|
#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(_DARWIN_FEATURE_64_BIT_INODE))
|
||||||
|
const TV tv = static_cast<TV>(st.st_mtimespec.tv_sec) * Timestamp::resolution() + st.st_mtimespec.tv_nsec/nsk;
|
||||||
|
return Timestamp(tv);
|
||||||
|
#elif POCO_OS == POCO_OS_LINUX
|
||||||
|
const TV tv = static_cast<TV>(st.st_mtim.tv_sec) * Timestamp::resolution() + st.st_mtim.tv_nsec/nsk;
|
||||||
|
return Timestamp(tv);
|
||||||
|
#else
|
||||||
return Timestamp::fromEpochTime(st.st_mtime);
|
return Timestamp::fromEpochTime(st.st_mtime);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
handleLastErrorImpl(_path);
|
handleLastErrorImpl(_path);
|
||||||
return 0;
|
return 0;
|
||||||
@ -244,10 +268,11 @@ void FileImpl::setLastModifiedImpl(const Timestamp& ts)
|
|||||||
{
|
{
|
||||||
poco_assert (!_path.empty());
|
poco_assert (!_path.empty());
|
||||||
|
|
||||||
struct utimbuf tb;
|
const ::time_t s = ts.epochTime();
|
||||||
tb.actime = ts.epochTime();
|
const ::suseconds_t us = ts.epochMicroseconds() % 1'000'000;
|
||||||
tb.modtime = ts.epochTime();
|
const ::timeval times[2] = { {s, us}, {s, us} };
|
||||||
if (utime(_path.c_str(), &tb) != 0)
|
|
||||||
|
if (::utimes(_path.c_str(), times) != 0)
|
||||||
handleLastErrorImpl(_path);
|
handleLastErrorImpl(_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +443,7 @@ void GlobTest::testGlob()
|
|||||||
files.clear();
|
files.clear();
|
||||||
Glob::glob("globtest/*/", files);
|
Glob::glob("globtest/*/", files);
|
||||||
translatePaths(files);
|
translatePaths(files);
|
||||||
assertTrue (files.size() == 3);
|
assertEqual (3, files.size());
|
||||||
assertTrue (files.find("globtest/include/") != files.end());
|
assertTrue (files.find("globtest/include/") != files.end());
|
||||||
assertTrue (files.find("globtest/src/") != files.end());
|
assertTrue (files.find("globtest/src/") != files.end());
|
||||||
assertTrue (files.find("globtest/testsuite/") != files.end());
|
assertTrue (files.find("globtest/testsuite/") != files.end());
|
||||||
@ -451,7 +451,7 @@ void GlobTest::testGlob()
|
|||||||
files.clear();
|
files.clear();
|
||||||
Glob::glob("globtest/testsuite/src/*", "globtest/testsuite/", files);
|
Glob::glob("globtest/testsuite/src/*", "globtest/testsuite/", files);
|
||||||
translatePaths(files);
|
translatePaths(files);
|
||||||
assertTrue (files.size() == 3);
|
assertEqual (3, files.size());
|
||||||
assertTrue (files.find("globtest/testsuite/src/test.h") != files.end());
|
assertTrue (files.find("globtest/testsuite/src/test.h") != files.end());
|
||||||
assertTrue (files.find("globtest/testsuite/src/test.c") != files.end());
|
assertTrue (files.find("globtest/testsuite/src/test.c") != files.end());
|
||||||
assertTrue (files.find("globtest/testsuite/src/main.c") != files.end());
|
assertTrue (files.find("globtest/testsuite/src/main.c") != files.end());
|
||||||
@ -460,7 +460,7 @@ void GlobTest::testGlob()
|
|||||||
files.clear();
|
files.clear();
|
||||||
Glob::glob("globtest/../*/testsuite/*/", files);
|
Glob::glob("globtest/../*/testsuite/*/", files);
|
||||||
translatePaths(files);
|
translatePaths(files);
|
||||||
assertTrue (files.size() == 1);
|
assertEqual (1, files.size());
|
||||||
|
|
||||||
File dir("globtest");
|
File dir("globtest");
|
||||||
dir.remove(true);
|
dir.remove(true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user