summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qlockfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qlockfile.cpp')
-rw-r--r--src/corelib/io/qlockfile.cpp98
1 files changed, 87 insertions, 11 deletions
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp
index 48317d07e0..aa84ce6bc1 100644
--- a/src/corelib/io/qlockfile.cpp
+++ b/src/corelib/io/qlockfile.cpp
@@ -2,6 +2,7 @@
**
** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org>
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -42,12 +43,36 @@
#include "qlockfile_p.h"
#include <QtCore/qthread.h>
+#include <QtCore/qcoreapplication.h>
#include <QtCore/qdeadlinetimer.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qfileinfo.h>
QT_BEGIN_NAMESPACE
+namespace {
+struct LockFileInfo
+{
+ qint64 pid;
+ QString appname;
+ QString hostname;
+ QByteArray hostid;
+ QByteArray bootid;
+};
+}
+
+static bool getLockInfo_helper(const QString &fileName, LockFileInfo *info);
+
+static QString machineName()
+{
+#ifdef Q_OS_WIN
+ // we don't use QSysInfo because it tries to do name resolution
+ return qEnvironmentVariable("COMPUTERNAME");
+#else
+ return QSysInfo::machineHostName();
+#endif
+}
+
/*!
\class QLockFile
\inmodule QtCore
@@ -291,13 +316,32 @@ bool QLockFile::tryLock(int timeout)
bool QLockFile::getLockInfo(qint64 *pid, QString *hostname, QString *appname) const
{
Q_D(const QLockFile);
- return d->getLockInfo(pid, hostname, appname);
+ LockFileInfo info;
+ if (!getLockInfo_helper(d->fileName, &info))
+ return false;
+ if (pid)
+ *pid = info.pid;
+ if (hostname)
+ *hostname = info.hostname;
+ if (appname)
+ *appname = info.appname;
+ return true;
+}
+
+QByteArray QLockFilePrivate::lockFileContents() const
+{
+ // Use operator% from the fast builder to avoid multiple memory allocations.
+ return QByteArray::number(QCoreApplication::applicationPid()) % '\n'
+ % processNameByPid(QCoreApplication::applicationPid()).toUtf8() % '\n'
+ % machineName().toUtf8() % '\n'
+ % QSysInfo::machineUniqueId() % '\n'
+ % QSysInfo::bootUniqueId() % '\n';
}
-bool QLockFilePrivate::getLockInfo(qint64 *pid, QString *hostname, QString *appname) const
+static bool getLockInfo_helper(const QString &fileName, LockFileInfo *info)
{
QFile reader(fileName);
- if (!reader.open(QIODevice::ReadOnly))
+ if (!reader.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
QByteArray pidLine = reader.readLine();
@@ -309,14 +353,46 @@ bool QLockFilePrivate::getLockInfo(qint64 *pid, QString *hostname, QString *appn
QByteArray hostNameLine = reader.readLine();
hostNameLine.chop(1);
- qint64 thePid = pidLine.toLongLong();
- if (pid)
- *pid = thePid;
- if (appname)
- *appname = QString::fromUtf8(appNameLine);
- if (hostname)
- *hostname = QString::fromUtf8(hostNameLine);
- return thePid > 0;
+ // prior to Qt 5.10, only the lines above were recorded
+ QByteArray hostId = reader.readLine();
+ hostId.chop(1);
+ QByteArray bootId = reader.readLine();
+ bootId.chop(1);
+
+ bool ok;
+ info->appname = QString::fromUtf8(appNameLine);
+ info->hostname = QString::fromUtf8(hostNameLine);
+ info->hostid = hostId;
+ info->bootid = bootId;
+ info->pid = pidLine.toLongLong(&ok);
+ return ok && info->pid > 0;
+}
+
+bool QLockFilePrivate::isApparentlyStale() const
+{
+ LockFileInfo info;
+ if (getLockInfo_helper(fileName, &info)) {
+ bool sameHost = info.hostname.isEmpty() || info.hostname == machineName();
+ if (!info.hostid.isEmpty()) {
+ // Override with the host ID, if we know it.
+ QByteArray ourHostId = QSysInfo::machineUniqueId();
+ if (!ourHostId.isEmpty())
+ sameHost = (ourHostId == info.hostid);
+ }
+
+ if (sameHost) {
+ if (!info.bootid.isEmpty()) {
+ // If we've rebooted, then the lock is definitely stale.
+ if (info.bootid != QSysInfo::bootUniqueId())
+ return true;
+ }
+ if (!isProcessRunning(info.pid, info.appname))
+ return true;
+ }
+ }
+
+ const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTimeUtc());
+ return staleLockTime > 0 && qAbs(age) > staleLockTime;
}
/*!