From c516a22e4de2465ea90c8e07a0577ae5ba6fb4ae Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 30 Nov 2018 20:46:20 -0500 Subject: [PATCH] session-helper: Improve HostCommand life-cycle handling Add flag that instructs the session-helper to kill the spawned command when the caller drops off the bus. Closes: #2326 Closes: #2365 Approved by: alexlarsson --- common/flatpak-utils-private.h | 1 + session-helper/flatpak-session-helper.c | 57 ++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/common/flatpak-utils-private.h b/common/flatpak-utils-private.h index 54d317b6..156462e2 100644 --- a/common/flatpak-utils-private.h +++ b/common/flatpak-utils-private.h @@ -39,6 +39,7 @@ typedef enum { FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV = 1 << 0, + FLATPAK_HOST_COMMAND_FLAGS_WATCH_BUS = 1 << 1, } FlatpakHostCommandFlags; diff --git a/session-helper/flatpak-session-helper.c b/session-helper/flatpak-session-helper.c index 7416b0de..396f2471 100644 --- a/session-helper/flatpak-session-helper.c +++ b/session-helper/flatpak-session-helper.c @@ -56,6 +56,7 @@ typedef struct GPid pid; char *client; guint child_watch; + gboolean watch_bus; } PidData; static void @@ -237,7 +238,8 @@ handle_host_command (FlatpakDevelopment *object, if (!g_variant_is_of_type (arg_fds, G_VARIANT_TYPE ("a{uh}")) || !g_variant_is_of_type (arg_envs, G_VARIANT_TYPE ("a{ss}")) || - (flags & ~FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV) != 0) + (flags & ~(FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV| + FLATPAK_HOST_COMMAND_FLAGS_WATCH_BUS)) != 0) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, @@ -353,6 +355,7 @@ handle_host_command (FlatpakDevelopment *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 = (flags & FLATPAK_HOST_COMMAND_FLAGS_WATCH_BUS) != 0; pid_data->child_watch = g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, child_watch_died, @@ -401,6 +404,48 @@ handle_host_command_signal (FlatpakDevelopment *object, 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; + GList *list = NULL, *l; + + g_hash_table_iter_init (&iter, client_pid_data_hash); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *)pid_data)) + { + 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; + 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, @@ -410,6 +455,16 @@ on_bus_acquired (GDBusConnection *connection, FlatpakDevelopment *devel; GError *error = NULL; + 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); + helper = flatpak_session_helper_skeleton_new (); flatpak_session_helper_set_version (FLATPAK_SESSION_HELPER (helper), 1);