summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2017-06-20 16:28:10 -0400
committerRay Strode <rstrode@redhat.com>2017-06-21 15:41:33 -0400
commitf21bc72afb63c2a0c38ab38244b925a3b00bd145 (patch)
treecc3a9e757b45fa3da515382e471e84ba8eb4bfbb
parent70728f6af3ca7313de3f44137f883eebd6242790 (diff)
downloadgnome-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.c104
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,