summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2016-07-20 17:23:05 -0400
committerRay Strode <rstrode@redhat.com>2017-03-01 10:56:55 -0500
commit96aa758c4ffe02a5bf950ab0a5b1e58474e10108 (patch)
treea3d8c5f10a8d1231cb6b047620dfe580cfc0a287
parent68af07c986c4f1747607e4bdc58cc9b4d2c56fab (diff)
downloadgdm-96aa758c4ffe02a5bf950ab0a5b1e58474e10108.tar.gz
slave: kill off clients from display when finished
When we're done with the display we need to kill off any clients that are lingering and close our own connection to the display. This is so, for instance, processes from the session don't stick around on a -noreset Xvnc server (or something) https://bugzilla.gnome.org/show_bug.cgi?id=776059
-rw-r--r--daemon/gdm-display.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 4b035d6f..0057e2ce 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -648,6 +648,35 @@ gdm_display_finish (GdmDisplay *self)
static void
gdm_display_disconnect (GdmDisplay *self)
{
+ /* These 3 bits are reserved/unused by the X protocol */
+ guint32 unused_bits = 0b11100000000000000000000000000000;
+ XID highest_client, client;
+ guint32 client_increment;
+ const xcb_setup_t *setup;
+
+ if (self->priv->xcb_connection == NULL) {
+ return;
+ }
+
+ setup = xcb_get_setup (self->priv->xcb_connection);
+
+ /* resource_id_mask is the bits given to each client for
+ * addressing resources */
+ highest_client = (XID) ~unused_bits & ~setup->resource_id_mask;
+ client_increment = setup->resource_id_mask + 1;
+
+ /* Kill every client but ourselves, then close our own connection
+ */
+ for (client = 0;
+ client <= highest_client;
+ client += client_increment) {
+
+ if (client != setup->resource_id_base)
+ xcb_kill_client (self->priv->xcb_connection, client);
+ }
+
+ xcb_flush (self->priv->xcb_connection);
+
g_clear_pointer (&self->priv->xcb_connection, xcb_disconnect);
}