[launcherlib] Use actual application name for sailjail'd apps. Fixes JB#52491

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 <tomi.leppanen@jolla.com>
pull/1/head
Tomi Leppänen 5 years ago
parent 1b1d2c3798
commit 5ae55df59e

@ -107,10 +107,11 @@ void Booster::initialize(int initialArgc, char ** initialArgv, int newBoosterLau
SingleInstancePluginEntry * pluginEntry = singleInstance->pluginEntry(); SingleInstancePluginEntry * pluginEntry = singleInstance->pluginEntry();
if (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 // 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!"); Logger::logWarning("Booster: Can't activate existing instance of the application!");
m_connection->sendExitValue(EXIT_FAILURE); m_connection->sendExitValue(EXIT_FAILURE);
@ -613,3 +614,37 @@ void Booster::resetOomAdj()
Logger::logError("Couldn't open '%s' for writing", PROC_OOM_ADJ_FILE); 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;
}

@ -194,6 +194,9 @@ private:
//! Helper method: load the library and find out address for "main". //! Helper method: load the library and find out address for "main".
void* loadMain(); void* loadMain();
//! Helper method: returns application name for to use for locking
std::string getLockedAppName();
//! Socket connection to invoker //! Socket connection to invoker
Connection* m_connection; Connection* m_connection;

@ -169,8 +169,6 @@ void Daemon::run(Booster *booster)
Logger::logDebug("Daemon: forking booster: %s", booster->boosterType().c_str()); Logger::logDebug("Daemon: forking booster: %s", booster->boosterType().c_str());
forkBooster(); forkBooster();
// Notify systemd that init is done // Notify systemd that init is done
if (m_notifySystemd) { if (m_notifySystemd) {
Logger::logDebug("Daemon: initialization done. Notify systemd\n"); Logger::logDebug("Daemon: initialization done. Notify systemd\n");

Loading…
Cancel
Save