diff options
author | Ray Strode <rstrode@redhat.com> | 2017-06-20 16:28:10 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2017-06-21 15:41:33 -0400 |
commit | f21bc72afb63c2a0c38ab38244b925a3b00bd145 (patch) | |
tree | cc3a9e757b45fa3da515382e471e84ba8eb4bfbb | |
parent | 70728f6af3ca7313de3f44137f883eebd6242790 (diff) | |
download | gnome-session-wip/rstrode/kill-bus-clients.tar.gz |
system: add api for detecting if this is the last session for a userwip/rstrode/kill-bus-clients
-rw-r--r-- | gnome-session/gsm-manager.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c index 012f3d3f..3adef392 100644 --- a/gnome-session/gsm-manager.c +++ b/gnome-session/gsm-manager.c @@ -39,6 +39,7 @@ #include "gsm-manager.h" #include "org.gnome.SessionManager.h" +#include "org.freedesktop.DBus.h" #ifdef HAVE_SYSTEMD #include <systemd/sd-journal.h> @@ -156,6 +157,7 @@ struct GsmManagerPrivate GsmSystem *system; GDBusConnection *connection; + GsmBus *bus_proxy; GsmExportedManager *skeleton; gboolean dbus_disconnected : 1; @@ -935,6 +937,92 @@ _client_stop (const char *id, return FALSE; } +static GPid * +get_pids_for_bus_clients (GsmManager *manager, + const char * const *bus_clients) +{ + GHashTable *process_id_hash; + GHashTableIter iter; + gpointer key, value; + GPid *process_ids; + int i, j; + + process_id_hash = g_hash_table_new (NULL, NULL); + + for (i = 0; bus_clients[i] != NULL; i++) { + gboolean ret; + GError *error; + guint pid; + + error = NULL; + ret = gsm_bus_call_get_connection_unix_process_id_sync (manager->priv->bus_proxy, + bus_clients[i], + &pid, + NULL, + &error); + + if (! ret) { + g_debug ("GsmManager: couldn't get process id of client '%s': %s", + bus_clients[i], error->message); + g_error_free (error); + continue; + } + + g_hash_table_add (process_id_hash, GUINT_TO_POINTER (pid)); + } + + j = 0; + process_ids = g_new0 (GPid, g_hash_table_size (process_id_hash) + 1); + g_hash_table_iter_init (&iter, process_id_hash); + while (g_hash_table_iter_next (&iter, &key, &value)) { + process_ids[j++] = (GPid) GPOINTER_TO_UINT (key); + } + + g_hash_table_unref (process_id_hash); + + return process_ids; +} + +static void +maybe_kill_bus_clients (GsmManager *manager) +{ + GsmSystem *system; + gboolean ret; + GError *error; + GPid *process_ids; + char **bus_clients; + int i; + + if (manager->priv->dbus_disconnected) + return; + + system = gsm_get_system (); + + if (!gsm_system_is_last_session_for_user (system)) + return; + + error = NULL; + ret = gsm_bus_call_list_names_sync (manager->priv->bus_proxy, + &bus_clients, + NULL, + &error); + + if (! ret) { + g_warning ("Unable to list bus clients: %s", error->message); + g_error_free (error); + return; + } + + process_ids = get_pids_for_bus_clients (manager, (const char * const *) bus_clients); + g_strfreev (bus_clients); + + for (i = 0; process_ids[i] != 0; i++) { + kill (process_ids[i], SIGTERM); + } + + free (process_ids); +} + static void do_phase_exit (GsmManager *manager) { @@ -944,6 +1032,8 @@ do_phase_exit (GsmManager *manager) NULL); } + maybe_kill_bus_clients (manager); + end_phase (manager); } @@ -3074,6 +3164,20 @@ register_manager (GsmManager *manager) exit (1); } + manager->priv->bus_proxy = gsm_bus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + NULL, + &error); + + if (error != NULL) { + g_critical ("error getting proxy to bus daemon: %s", error->message); + g_error_free (error); + + exit (1); + } + skeleton = gsm_exported_manager_skeleton_new (); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton), connection, |