aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2017-03-06 17:28:14 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2017-03-08 11:47:56 +0000
commite760693b84bc88eba78b1d3e08899ad6b5c80ac5 (patch)
tree0e96f53585778d0ba9b852023acc9f1e59f1b118 /src/lib/corelib
parentad96a388f7e31cf7b8260de7631319e5c76613ec (diff)
Handle sub-second timestamps correctly on Unix
There are file systems that support a more fine-grained resolution than the traditional second. [ChangeLog] Sub-second timestamp resolutions are now supported on Unix systems. Task-number: QBS-1110 Change-Id: I7c819882497511462d868584eb059ac392b155d9 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'src/lib/corelib')
-rw-r--r--src/lib/corelib/jsextensions/file.cpp2
-rw-r--r--src/lib/corelib/tools/fileinfo.cpp4
-rw-r--r--src/lib/corelib/tools/filetime.cpp72
-rw-r--r--src/lib/corelib/tools/filetime.h58
-rw-r--r--src/lib/corelib/tools/persistence.cpp2
5 files changed, 78 insertions, 60 deletions
diff --git a/src/lib/corelib/jsextensions/file.cpp b/src/lib/corelib/jsextensions/file.cpp
index bb60edce3..4368c4f1b 100644
--- a/src/lib/corelib/jsextensions/file.cpp
+++ b/src/lib/corelib/jsextensions/file.cpp
@@ -213,7 +213,7 @@ QScriptValue File::js_lastModified(QScriptContext *context, QScriptEngine *engin
const FileTime timestamp = FileInfo(filePath).lastModified();
ScriptEngine * const se = static_cast<ScriptEngine *>(engine);
se->addFileLastModifiedResult(filePath, timestamp);
- return static_cast<qsreal>(timestamp.m_fileTime);
+ return timestamp.asDouble();
}
QScriptValue File::js_makePath(QScriptContext *context, QScriptEngine *engine)
diff --git a/src/lib/corelib/tools/fileinfo.cpp b/src/lib/corelib/tools/fileinfo.cpp
index 61a0ab8ed..94536f6e3 100644
--- a/src/lib/corelib/tools/fileinfo.cpp
+++ b/src/lib/corelib/tools/fileinfo.cpp
@@ -341,12 +341,12 @@ bool FileInfo::exists() const
FileTime FileInfo::lastModified() const
{
- return m_stat.st_mtime;
+ return m_stat.st_mtim;
}
FileTime FileInfo::lastStatusChange() const
{
- return m_stat.st_ctime;
+ return m_stat.st_ctim;
}
bool FileInfo::isDir() const
diff --git a/src/lib/corelib/tools/filetime.cpp b/src/lib/corelib/tools/filetime.cpp
index ac917260e..794548f27 100644
--- a/src/lib/corelib/tools/filetime.cpp
+++ b/src/lib/corelib/tools/filetime.cpp
@@ -45,7 +45,6 @@
#include <QtCore/qt_windows.h>
#else
#include <QtCore/qdatetime.h>
-#include <time.h>
#endif
namespace qbs {
@@ -57,33 +56,55 @@ template<> struct CompileTimeAssert<true> {};
#endif
FileTime::FileTime()
- : m_fileTime(0)
{
#ifdef Q_OS_WIN
static CompileTimeAssert<sizeof(FileTime::InternalType) == sizeof(FILETIME)> internal_type_has_wrong_size;
Q_UNUSED(internal_type_has_wrong_size);
+ m_fileTime = 0;
+#else
+ m_fileTime = {0, 0};
#endif
}
-bool FileTime::operator < (const FileTime &rhs) const
+FileTime::FileTime(const FileTime::InternalType &ft) : m_fileTime(ft)
+{
+#ifndef Q_OS_WIN
+ if (m_fileTime.tv_sec == 0)
+ m_fileTime.tv_nsec = 0; // stat() sets only the first member to 0 for non-existing files.
+#endif
+}
+
+int FileTime::compare(const FileTime &other) const
{
#ifdef Q_OS_WIN
const FILETIME *const t1 = reinterpret_cast<const FILETIME *>(&m_fileTime);
- const FILETIME *const t2 = reinterpret_cast<const FILETIME *>(&rhs.m_fileTime);
- return CompareFileTime(t1, t2) < 0;
+ const FILETIME *const t2 = reinterpret_cast<const FILETIME *>(&other.m_fileTime);
+ return CompareFileTime(t1, t2);
#else
- return m_fileTime < rhs.m_fileTime;
+ if (m_fileTime.tv_sec < other.m_fileTime.tv_sec)
+ return -1;
+ if (m_fileTime.tv_sec > other.m_fileTime.tv_sec)
+ return 1;
+ if (m_fileTime.tv_nsec < other.m_fileTime.tv_nsec)
+ return -1;
+ if (m_fileTime.tv_nsec > other.m_fileTime.tv_nsec)
+ return 1;
+ return 0;
#endif
}
void FileTime::clear()
{
+#ifdef Q_OS_WIN
m_fileTime = 0;
+#else
+ m_fileTime = { 0, 0 };
+#endif
}
bool FileTime::isValid() const
{
- return m_fileTime != 0;
+ return *this != FileTime();
}
FileTime FileTime::currentTime()
@@ -96,7 +117,9 @@ FileTime FileTime::currentTime()
SystemTimeToFileTime(&st, ft);
return result;
#else
- return time(0);
+ InternalType t;
+ clock_gettime(CLOCK_REALTIME, &t);
+ return t;
#endif
}
@@ -118,7 +141,16 @@ FileTime FileTime::oldestTime()
SystemTimeToFileTime(&st, ft);
return result;
#else
- return 1;
+ return FileTime({1, 0});
+#endif
+}
+
+double FileTime::asDouble() const
+{
+#ifdef Q_OS_WIN
+ return static_cast<double>(m_fileTime);
+#else
+ return static_cast<double>(m_fileTime.tv_sec);
#endif
}
@@ -135,10 +167,30 @@ QString FileTime::toString() const
return result;
#else
QDateTime dt;
- dt.setTime_t(m_fileTime);
+ dt.setMSecsSinceEpoch(m_fileTime.tv_sec * 1000 + m_fileTime.tv_nsec / 1000000);
return dt.toString();
#endif
}
+void qbs::Internal::FileTime::store(PersistentPool &pool) const
+{
+#ifdef Q_OS_WIN
+ pool.store(static_cast<quint64>(m_fileTime));
+#else
+ pool.store(static_cast<qint64>(m_fileTime.tv_sec));
+ pool.store(static_cast<qint64>(m_fileTime.tv_nsec));
+#endif
+}
+
+void qbs::Internal::FileTime::load(PersistentPool &pool)
+{
+#ifdef Q_OS_WIN
+ m_fileTime = pool.load<quint64>();
+#else
+ m_fileTime.tv_sec = pool.load<qint64>();
+ m_fileTime.tv_nsec = pool.load<qint64>();
+#endif
+}
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/tools/filetime.h b/src/lib/corelib/tools/filetime.h
index 1c8884d9d..83e09cf68 100644
--- a/src/lib/corelib/tools/filetime.h
+++ b/src/lib/corelib/tools/filetime.h
@@ -56,7 +56,7 @@ class FileTime
{
public:
#if defined(Q_OS_UNIX)
- typedef time_t InternalType;
+ typedef timespec InternalType;
#elif defined(Q_OS_WIN)
typedef quint64 InternalType;
#else
@@ -64,19 +64,18 @@ public:
#endif
FileTime();
- FileTime(const InternalType &ft)
- : m_fileTime(ft)
- { }
+ FileTime(const InternalType &ft);
void store(PersistentPool &pool) const;
void load(PersistentPool &pool);
- bool operator < (const FileTime &rhs) const;
- bool operator > (const FileTime &rhs) const;
- bool operator <= (const FileTime &rhs) const;
- bool operator >= (const FileTime &rhs) const;
- bool operator == (const FileTime &rhs) const;
- bool operator != (const FileTime &rhs) const;
+ bool operator<(const FileTime &rhs) const { return compare(rhs) < 0; }
+ bool operator>(const FileTime &rhs) const { return compare(rhs) > 0; }
+ bool operator<=(const FileTime &rhs) const { return !operator>(rhs); }
+ bool operator>=(const FileTime &rhs) const { return !operator<(rhs); }
+ bool operator==(const FileTime &rhs) const { return compare(rhs) == 0; }
+ bool operator!= (const FileTime &rhs) const { return !operator==(rhs); }
+ int compare(const FileTime &other) const;
void clear();
bool isValid() const;
@@ -85,45 +84,12 @@ public:
static FileTime currentTime();
static FileTime oldestTime();
- friend class FileInfo;
+ double asDouble() const;
+
+private:
InternalType m_fileTime;
};
-inline void FileTime::store(PersistentPool &pool) const
-{
- pool.store(static_cast<quint64>(m_fileTime));
-}
-
-inline void FileTime::load(PersistentPool &pool)
-{
- m_fileTime = pool.load<quint64>();
-}
-
-inline bool FileTime::operator > (const FileTime &rhs) const
-{
- return rhs < *this;
-}
-
-inline bool FileTime::operator <= (const FileTime &rhs) const
-{
- return operator < (rhs) || operator == (rhs);
-}
-
-inline bool FileTime::operator >= (const FileTime &rhs) const
-{
- return operator > (rhs) || operator == (rhs);
-}
-
-inline bool FileTime::operator == (const FileTime &rhs) const
-{
- return m_fileTime == rhs.m_fileTime;
-}
-
-inline bool FileTime::operator != (const FileTime &rhs) const
-{
- return !operator==(rhs);
-}
-
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp
index 98ac177e9..5e92fa493 100644
--- a/src/lib/corelib/tools/persistence.cpp
+++ b/src/lib/corelib/tools/persistence.cpp
@@ -50,7 +50,7 @@
namespace qbs {
namespace Internal {
-static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-97";
+static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-98";
PersistentPool::PersistentPool(Logger &logger) : m_logger(logger)
{