mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-07-27 00:35:27 -04:00
Correct latent single instance lock file preventing launch
* Fixes #893
This commit is contained in:
parent
4b6dbcaec4
commit
9ebe0b61eb
2 changed files with 44 additions and 28 deletions
|
@ -81,8 +81,8 @@ Application::Application(int& argc, char** argv)
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
, m_unixSignalNotifier(nullptr)
|
, m_unixSignalNotifier(nullptr)
|
||||||
#endif
|
#endif
|
||||||
, alreadyRunning(false)
|
, m_alreadyRunning(false)
|
||||||
, lock(nullptr)
|
, m_lockFile(nullptr)
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
|
#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
|
||||||
installNativeEventFilter(new XcbEventFilter());
|
installNativeEventFilter(new XcbEventFilter());
|
||||||
|
@ -99,40 +99,56 @@ Application::Application(int& argc, char** argv)
|
||||||
}
|
}
|
||||||
QString identifier = "keepassxc";
|
QString identifier = "keepassxc";
|
||||||
if (!userName.isEmpty()) {
|
if (!userName.isEmpty()) {
|
||||||
identifier.append("-");
|
identifier += "-" + userName;
|
||||||
identifier.append(userName);
|
}
|
||||||
#ifdef QT_DEBUG
|
#ifdef QT_DEBUG
|
||||||
// In DEBUG mode don't interfere with Release instances
|
// In DEBUG mode don't interfere with Release instances
|
||||||
identifier.append("-DEBUG");
|
identifier += "-DEBUG";
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
QString socketName = identifier + ".socket";
|
QString socketName = identifier + ".socket";
|
||||||
QString lockName = identifier + ".lock";
|
QString lockName = identifier + ".lock";
|
||||||
|
|
||||||
// According to documentation we should use RuntimeLocation on *nixes, but even Qt doesn't respect
|
// According to documentation we should use RuntimeLocation on *nixes, but even Qt doesn't respect
|
||||||
// this and creates sockets in TempLocation, so let's be consistent.
|
// this and creates sockets in TempLocation, so let's be consistent.
|
||||||
lock = new QLockFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + lockName);
|
m_lockFile = new QLockFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + lockName);
|
||||||
lock->setStaleLockTime(0);
|
m_lockFile->setStaleLockTime(0);
|
||||||
lock->tryLock();
|
m_lockFile->tryLock();
|
||||||
switch (lock->error()) {
|
|
||||||
|
switch (m_lockFile->error()) {
|
||||||
case QLockFile::NoError:
|
case QLockFile::NoError:
|
||||||
server.setSocketOptions(QLocalServer::UserAccessOption);
|
// No existing lock was found, start listener
|
||||||
server.listen(socketName);
|
m_lockServer.setSocketOptions(QLocalServer::UserAccessOption);
|
||||||
connect(&server, SIGNAL(newConnection()), this, SIGNAL(anotherInstanceStarted()));
|
m_lockServer.listen(socketName);
|
||||||
|
connect(&m_lockServer, SIGNAL(newConnection()), this, SIGNAL(anotherInstanceStarted()));
|
||||||
break;
|
break;
|
||||||
case QLockFile::LockFailedError: {
|
case QLockFile::LockFailedError: {
|
||||||
alreadyRunning = true;
|
|
||||||
// notify the other instance
|
|
||||||
// try several times, in case the other instance is still starting up
|
|
||||||
if (config()->get("SingleInstance").toBool()) {
|
if (config()->get("SingleInstance").toBool()) {
|
||||||
|
// Attempt to connect to the existing instance
|
||||||
QLocalSocket client;
|
QLocalSocket client;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
client.connectToServer(socketName);
|
client.connectToServer(socketName);
|
||||||
if (client.waitForConnected(150)) {
|
if (client.waitForConnected(150)) {
|
||||||
|
// Connection succeeded, this will raise the existing window if minimized
|
||||||
client.abort();
|
client.abort();
|
||||||
|
m_alreadyRunning = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_alreadyRunning) {
|
||||||
|
// If we get here then the original instance is likely dead
|
||||||
|
qWarning() << QCoreApplication::translate("Main",
|
||||||
|
"Existing single-instance lock file is invalid. Launching new instance.")
|
||||||
|
.toUtf8().constData();
|
||||||
|
|
||||||
|
// forceably reset the lock file
|
||||||
|
m_lockFile->removeStaleLockFile();
|
||||||
|
m_lockFile->tryLock();
|
||||||
|
// start the listen server
|
||||||
|
m_lockServer.setSocketOptions(QLocalServer::UserAccessOption);
|
||||||
|
m_lockServer.listen(socketName);
|
||||||
|
connect(&m_lockServer, SIGNAL(newConnection()), this, SIGNAL(anotherInstanceStarted()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -145,10 +161,10 @@ Application::Application(int& argc, char** argv)
|
||||||
|
|
||||||
Application::~Application()
|
Application::~Application()
|
||||||
{
|
{
|
||||||
server.close();
|
m_lockServer.close();
|
||||||
if (lock) {
|
if (m_lockFile) {
|
||||||
lock->unlock();
|
m_lockFile->unlock();
|
||||||
delete lock;
|
delete m_lockFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,6 +259,6 @@ bool Application::isAlreadyRunning() const
|
||||||
// In DEBUG mode we can run unlimited instances
|
// In DEBUG mode we can run unlimited instances
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
return config()->get("SingleInstance").toBool() && alreadyRunning;
|
return config()->get("SingleInstance").toBool() && m_alreadyRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,9 +60,9 @@ private:
|
||||||
static void handleUnixSignal(int sig);
|
static void handleUnixSignal(int sig);
|
||||||
static int unixSignalSocket[2];
|
static int unixSignalSocket[2];
|
||||||
#endif
|
#endif
|
||||||
bool alreadyRunning;
|
bool m_alreadyRunning;
|
||||||
QLockFile* lock;
|
QLockFile* m_lockFile;
|
||||||
QLocalServer server;
|
QLocalServer m_lockServer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_APPLICATION_H
|
#endif // KEEPASSX_APPLICATION_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue