summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qlockfile_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qlockfile_unix.cpp')
-rw-r--r--src/corelib/io/qlockfile_unix.cpp58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index b817a24c74..d6ea2f1f2d 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org>
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -48,6 +49,15 @@
#include <signal.h> // kill
#include <unistd.h> // gethostname
+#if defined(Q_OS_OSX)
+# include <libproc.h>
+#elif defined(Q_OS_LINUX)
+# include <unistd.h>
+# include <cstdio>
+#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS)
+# include <sys/user.h>
+#endif
+
QT_BEGIN_NAMESPACE
static QByteArray localHostName() // from QHostInfo::localHostName(), modified to return a QByteArray
@@ -185,16 +195,54 @@ bool QLockFilePrivate::isApparentlyStale() const
{
qint64 pid;
QString hostname, appname;
- if (!getLockInfo(&pid, &hostname, &appname))
- return false;
- if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {
- if (::kill(pid, 0) == -1 && errno == ESRCH)
- return true; // PID doesn't exist anymore
+ if (getLockInfo(&pid, &hostname, &appname)) {
+ if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {
+ if (::kill(pid, 0) == -1 && errno == ESRCH)
+ return true; // PID doesn't exist anymore
+ const QString processName = processNameByPid(pid);
+ if (!processName.isEmpty()) {
+ QFileInfo fi(appname);
+ if (fi.isSymLink())
+ fi.setFile(fi.symLinkTarget());
+ if (processName != fi.fileName())
+ return true; // PID got reused by a different application.
+ }
+ }
}
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
return staleLockTime > 0 && age > staleLockTime;
}
+QString QLockFilePrivate::processNameByPid(qint64 pid)
+{
+#if defined(Q_OS_OSX)
+ char name[1024];
+ proc_name(pid, name, sizeof(name) / sizeof(char));
+ return QString::fromUtf8(name);
+#elif defined(Q_OS_LINUX)
+ if (!QFile::exists(QStringLiteral("/proc/version")))
+ return QString();
+ char exePath[64];
+ char buf[PATH_MAX];
+ memset(buf, 0, sizeof(buf));
+ sprintf(exePath, "/proc/%lld/exe", pid);
+ if (readlink(exePath, buf, sizeof(buf)) < 0) {
+ // The pid is gone. Return some invalid process name to fail the test.
+ return QStringLiteral("/ERROR/");
+ }
+ return QFileInfo(QString::fromUtf8(buf)).fileName();
+#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS)
+ kinfo_proc *proc = kinfo_getproc(pid);
+ if (!proc)
+ return QString();
+ QString name = QString::fromUtf8(proc->ki_comm);
+ free(proc);
+ return name;
+#else
+ return QString();
+#endif
+}
+
void QLockFile::unlock()
{
Q_D(QLockFile);