From 5ae55df59ee8e8ef426e10095f6cc2428ff4e96e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Lepp=C3=A4nen?= Date: Wed, 16 Dec 2020 15:16:24 +0200 Subject: [PATCH] [launcherlib] Use actual application name for sailjail'd apps. Fixes JB#52491 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Applications launched via sailjail have their appName set to /usr/bin/sailjail and that is used to set single instance lock. That results in not being able to launch multiple different applications simultaneously via mapplauncher. Mitigate this by using actual application name for single instance lock. This implements a very simple way of deducing the application binary path from sailjail's arguments. It works for most cases and the remaining cases can be worked around. Signed-off-by: Tomi Leppänen --- src/launcherlib/booster.cpp | 39 +++++++++++++++++++++++++++++++++++-- src/launcherlib/booster.h | 3 +++ src/launcherlib/daemon.cpp | 2 -- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/launcherlib/booster.cpp b/src/launcherlib/booster.cpp index b82de92..93c8a02 100644 --- a/src/launcherlib/booster.cpp +++ b/src/launcherlib/booster.cpp @@ -107,10 +107,11 @@ void Booster::initialize(int initialArgc, char ** initialArgv, int newBoosterLau SingleInstancePluginEntry * pluginEntry = singleInstance->pluginEntry(); if (pluginEntry) { - if (!pluginEntry->lockFunc(m_appData->appName().c_str())) + std::string lockedAppName = getLockedAppName(); + if (!pluginEntry->lockFunc(lockedAppName.c_str())) { // Try to activate the window of the existing instance - if (!pluginEntry->activateExistingInstanceFunc(m_appData->appName().c_str())) + if (!pluginEntry->activateExistingInstanceFunc(lockedAppName.c_str())) { Logger::logWarning("Booster: Can't activate existing instance of the application!"); m_connection->sendExitValue(EXIT_FAILURE); @@ -613,3 +614,37 @@ void Booster::resetOomAdj() Logger::logError("Couldn't open '%s' for writing", PROC_OOM_ADJ_FILE); } } + +std::string Booster::getLockedAppName() +{ + std::string name = m_appData->appName(); + if (name == "/usr/bin/sailjail") { + // This doesn't implement sailjail's parsing logic but instead + // has some assumptions about the arguments: + // - If there is --, then the application is + // the next argument after that. + // - If there is an argument that begins with /usr/bin/, + // then the application is that argument. + // The one that is found first is used as the application name. + // Otherwise it can not be deduced and the original value is used. + // + // If you want to give a value to sailjail that begins with /usr/bin/, + // use the long format with '=' character between the argument and the + // value. + // If the application is specified without /usr/bin, + // then adding -- before the application name allows this to work. + const char **ptr = m_appData->argv()+1; + for (int i = 1; i < m_appData->argc(); i++, ptr++) { + if (strcmp(*ptr, "--") == 0) { + if (i+1 < m_appData->argc()) { + name = *(++ptr); + break; + } + } else if (strncmp(*ptr, "/usr/bin/", 9) == 0) { + name = *ptr; + break; + } + } + } + return name; +} diff --git a/src/launcherlib/booster.h b/src/launcherlib/booster.h index feafada..2e7f437 100644 --- a/src/launcherlib/booster.h +++ b/src/launcherlib/booster.h @@ -194,6 +194,9 @@ private: //! Helper method: load the library and find out address for "main". void* loadMain(); + //! Helper method: returns application name for to use for locking + std::string getLockedAppName(); + //! Socket connection to invoker Connection* m_connection; diff --git a/src/launcherlib/daemon.cpp b/src/launcherlib/daemon.cpp index c1dcaf6..a1c0edf 100644 --- a/src/launcherlib/daemon.cpp +++ b/src/launcherlib/daemon.cpp @@ -169,8 +169,6 @@ void Daemon::run(Booster *booster) Logger::logDebug("Daemon: forking booster: %s", booster->boosterType().c_str()); forkBooster(); - - // Notify systemd that init is done if (m_notifySystemd) { Logger::logDebug("Daemon: initialization done. Notify systemd\n");