portal: Suport a watch-bus flag

This behaves just the same as the watch-bus flag that
was reently added to HostCommand.

Closes: #2439
Approved by: alexlarsson
This commit is contained in:
Matthias Clasen
2018-12-16 14:36:57 -05:00
committed by Atomic Bot
parent f53ef41032
commit 9a1febd981
3 changed files with 67 additions and 1 deletions

View File

@@ -80,6 +80,12 @@
Spawn without network (equivalent of the unshare=network option of flatpak run).
</para></listitem>
</varlistentry>
<varlistentry>
<term>16</term>
<listitem><para>
Kill the sandbox when the caller disappears from the session bus.
</para></listitem>
</varlistentry>
</variablelist>
The following options are supported:

View File

@@ -117,6 +117,7 @@ typedef struct
GPid pid;
char *client;
guint child_watch;
gboolean watch_bus;
} PidData;
static void
@@ -607,6 +608,7 @@ handle_spawn (PortalFlatpak *object,
pid_data = g_new0 (PidData, 1);
pid_data->pid = pid;
pid_data->client = g_strdup (g_dbus_method_invocation_get_sender (invocation));
pid_data->watch_bus = (arg_flags & FLATPAK_SPAWN_FLAGS_WATCH_BUS) != 0;
pid_data->child_watch = g_child_watch_add_full (G_PRIORITY_DEFAULT,
pid,
child_watch_died,
@@ -690,6 +692,52 @@ authorize_method_handler (GDBusInterfaceSkeleton *interface,
return TRUE;
}
static void
name_owner_changed (GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
const char *name, *from, *to;
g_variant_get (parameters, "(&s&s&s)", &name, &from, &to);
if (name[0] == ':' &&
strcmp (name, from) == 0 &&
strcmp (to, "") == 0)
{
GHashTableIter iter;
PidData *pid_data = NULL;
gpointer value = NULL;
GList *list = NULL, *l;
g_hash_table_iter_init (&iter, client_pid_data_hash);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
pid_data = value;
if (pid_data->watch_bus && g_str_equal (pid_data->client, name))
list = g_list_prepend (list, pid_data);
}
for (l = list; l; l = l->next)
{
pid_data = l->data;
g_debug ("%s dropped off the bus, killing %d", pid_data->client, pid_data->pid);
killpg (pid_data->pid, SIGINT);
}
g_list_free (list);
}
}
#define DBUS_NAME_DBUS "org.freedesktop.DBus"
#define DBUS_INTERFACE_DBUS DBUS_NAME_DBUS
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
static void
on_bus_acquired (GDBusConnection *connection,
const gchar *name,
@@ -701,6 +749,16 @@ on_bus_acquired (GDBusConnection *connection,
portal = portal_flatpak_skeleton_new ();
g_dbus_connection_signal_subscribe (connection,
DBUS_NAME_DBUS,
DBUS_INTERFACE_DBUS,
"NameOwnerChanged",
DBUS_PATH_DBUS,
NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
name_owner_changed,
NULL, NULL);
g_object_set_data_full (G_OBJECT (portal), "track-alive", GINT_TO_POINTER (42), skeleton_died_cb);
g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (portal),

View File

@@ -26,11 +26,13 @@ typedef enum {
FLATPAK_SPAWN_FLAGS_LATEST_VERSION = 1 << 1,
FLATPAK_SPAWN_FLAGS_SANDBOX = 1 << 2,
FLATPAK_SPAWN_FLAGS_NO_NETWORK = 1 << 3,
FLATPAK_SPAWN_FLAGS_WATCH_BUS = 1 << 4,
} FlatpakSpawnFlags;
#define FLATPAK_SPAWN_FLAGS_ALL (FLATPAK_SPAWN_FLAGS_CLEAR_ENV | \
FLATPAK_SPAWN_FLAGS_LATEST_VERSION | \
FLATPAK_SPAWN_FLAGS_SANDBOX | \
FLATPAK_SPAWN_FLAGS_NO_NETWORK)
FLATPAK_SPAWN_FLAGS_NO_NETWORK | \
FLATPAK_SPAWN_FLAGS_WATCH_BUS)
#endif /* __FLATPAK_PORTAL_H__ */