diff options
-rw-r--r-- | src/corelib/io/qlockfile.cpp | 3 | ||||
-rw-r--r-- | src/corelib/io/qlockfile_unix.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qlockfile_win.cpp | 2 | ||||
-rw-r--r-- | tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp | 28 |
4 files changed, 33 insertions, 2 deletions
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index cb1ff93ad3..48317d07e0 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -44,6 +44,7 @@ #include <QtCore/qthread.h> #include <QtCore/qdeadlinetimer.h> #include <QtCore/qdatetime.h> +#include <QtCore/qfileinfo.h> QT_BEGIN_NAMESPACE @@ -226,6 +227,8 @@ bool QLockFile::tryLock(int timeout) return false; case LockFailedError: if (!d->isLocked && d->isApparentlyStale()) { + if (Q_UNLIKELY(QFileInfo(d->fileName).lastModified() > QDateTime::currentDateTime())) + qInfo("QLockFile: Lock file '%ls' has a modification time in the future", qUtf16Printable(d->fileName)); // Stale lock from another thread/process // Ensure two processes don't remove it at the same time QLockFile rmlock(d->fileName + QLatin1String(".rmlock")); diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 3a80014c00..5a02741727 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -247,7 +247,7 @@ bool QLockFilePrivate::isApparentlyStale() const } } const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); - return staleLockTime > 0 && age > staleLockTime; + return staleLockTime > 0 && qAbs(age) > staleLockTime; } QString QLockFilePrivate::processNameByPid(qint64 pid) diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index baaff8da17..4b43181686 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -160,7 +160,7 @@ bool QLockFilePrivate::isApparentlyStale() const Q_UNUSED(appname); #endif // Q_OS_WINRT const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); - return staleLockTime > 0 && age > staleLockTime; + return staleLockTime > 0 && qAbs(age) > staleLockTime; } QString QLockFilePrivate::processNameByPid(qint64 pid) diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index a13ff0358a..d2f345feb5 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -34,6 +34,7 @@ #include <qsysinfo.h> #if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) #include <unistd.h> +#include <sys/time.h> #elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT) # include <qt_windows.h> #endif @@ -59,6 +60,7 @@ private slots: void noPermissions(); void noPermissionsWindows(); void corruptedLockFile(); + void corruptedLockFileInTheFuture(); private: static bool overwritePidInLockFile(const QString &filePath, qint64 pid); @@ -521,6 +523,32 @@ void tst_QLockFile::corruptedLockFile() QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); } +void tst_QLockFile::corruptedLockFileInTheFuture() +{ +#if !defined(Q_OS_UNIX) + QSKIP("This tests needs utimes"); +#else + // This test is the same as the previous one, but the corruption was so there is a corrupted + // .rmlock whose timestamp is in the future + + const QString fileName = dir.path() + "/corruptedLockFile.rmlock"; + + { + QFile file(fileName); + QVERIFY(file.open(QFile::WriteOnly)); + } + + struct timeval times[2]; + gettimeofday(times, 0); + times[1].tv_sec = (times[0].tv_sec += 600); + times[1].tv_usec = times[0].tv_usec; + utimes(fileName.toLocal8Bit(), times); + + QTest::ignoreMessage(QtInfoMsg, "QLockFile: Lock file '" + fileName.toUtf8() + "' has a modification time in the future"); + corruptedLockFile(); +#endif +} + bool tst_QLockFile::overwritePidInLockFile(const QString &filePath, qint64 pid) { QFile f(filePath); |