Talk to the portal when running inside a flatpak

When we detect that we are running inside a flatpak, talk to the
flatpak portal D-Bus service instead of the session daemon. This
is necessary because flatpak uses pid namespace isolation (see
man pid_namespaces(7)) and thus the pid needs to be translated
from the flatpak pid namespace to the host namespace. This
translation is happening inside the GameMode xdg-desktop-portal.
This commit is contained in:
Christian Kellner 2019-05-20 17:19:21 +02:00
parent 536d687c9a
commit 0c36f3a6b0

View File

@ -36,6 +36,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <systemd/sd-bus.h> #include <systemd/sd-bus.h>
#include <unistd.h> #include <unistd.h>
@ -44,9 +46,24 @@ POSSIBILITY OF SUCH DAMAGE.
#define DAEMON_DBUS_PATH "/com/feralinteractive/GameMode" #define DAEMON_DBUS_PATH "/com/feralinteractive/GameMode"
#define DAEMON_DBUS_IFACE "com.feralinteractive.GameMode" #define DAEMON_DBUS_IFACE "com.feralinteractive.GameMode"
#define PORTAL_DBUS_NAME "org.freedesktop.portal.Desktop"
#define PORTAL_DBUS_PATH "/org/freedesktop/portal/desktop"
#define PORTAL_DBUS_IFACE "org.freedesktop.portal.GameMode"
// Storage for error strings // Storage for error strings
static char error_string[512] = { 0 }; static char error_string[512] = { 0 };
// Helper to check if we are running inside a flatpak
static int in_flatpak(void)
{
struct stat sb;
int r;
r = lstat("/.flatpak-info", &sb);
return r == 0 && sb.st_size > 0;
}
// Simple requestor function for a gamemode // Simple requestor function for a gamemode
static int gamemode_request(const char *function, int arg) static int gamemode_request(const char *function, int arg)
{ {
@ -65,11 +82,18 @@ static int gamemode_request(const char *function, int arg)
"Could not connect to bus: %s", "Could not connect to bus: %s",
strerror(-ret)); strerror(-ret));
} else { } else {
int native = !in_flatpak();
// If we are inside a flatpak we need to talk to the portal instead
const char *dest = native ? DAEMON_DBUS_NAME : PORTAL_DBUS_NAME;
const char *path = native ? DAEMON_DBUS_PATH : PORTAL_DBUS_PATH;
const char *iface = native ? DAEMON_DBUS_IFACE : PORTAL_DBUS_IFACE;
// Attempt to send the requested function // Attempt to send the requested function
ret = sd_bus_call_method(bus, ret = sd_bus_call_method(bus,
DAEMON_DBUS_NAME, dest,
DAEMON_DBUS_PATH, path,
DAEMON_DBUS_IFACE, iface,
function, function,
&err, &err,
&msg, &msg,
@ -79,11 +103,12 @@ static int gamemode_request(const char *function, int arg)
if (ret < 0) { if (ret < 0) {
snprintf(error_string, snprintf(error_string,
sizeof(error_string), sizeof(error_string),
"Could not call method %s on com.feralinteractive.GameMode\n" "Could not call method %s on %s\n"
"\t%s\n" "\t%s\n"
"\t%s\n" "\t%s\n"
"\t%s\n", "\t%s\n",
function, function,
dest,
err.name, err.name,
err.message, err.message,
strerror(-ret)); strerror(-ret));