[gnome-session/benzea/cleanup-wayland] Cleanup wayland socket at logout time




commit 1fc0a26c9cc5b0771ea1fbab34b177e5b151627e
Author: Benjamin Berg <bberg redhat com>
Date:   Fri Dec 11 14:19:29 2020 +0100

    Cleanup wayland socket at logout time
    
    For the non-systemd case, just remove the socket when the daemon shuts
    down. For systemd, add another helper into gnome-session-ctl that
    deletes the socket and also unsets the variable on the systemd side.
    
    Fixes: #75

 data/gnome-session-cleanup-wayland.service.in | 11 ++++++
 data/gnome-session-shutdown.target            |  3 ++
 data/meson.build                              |  1 +
 gnome-session/gsm-manager.c                   | 23 +++++++++++
 tools/gnome-session-ctl.c                     | 56 +++++++++++++++++++++++++++
 5 files changed, 94 insertions(+)
---
diff --git a/data/gnome-session-cleanup-wayland.service.in b/data/gnome-session-cleanup-wayland.service.in
new file mode 100644
index 000000000..8e70da011
--- /dev/null
+++ b/data/gnome-session-cleanup-wayland.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=Delete wayland socket at logout time
+
+# Allow exit.target to start even if this unit is started with replace-irreversibly.
+# For this to work, we also need to be in the root slice.
+DefaultDependencies=no
+
+[Service]
+Type=notify
+ExecStart=@libexecdir@/gnome-session-ctl --cleanup-wayland
+Slice=-.slice
diff --git a/data/gnome-session-shutdown.target b/data/gnome-session-shutdown.target
index 2c3d19632..4c3183eb6 100644
--- a/data/gnome-session-shutdown.target
+++ b/data/gnome-session-shutdown.target
@@ -31,3 +31,6 @@ StopWhenUnneeded=true
 # Historic bug: https://bugzilla.gnome.org/show_bug.cgi?id=764029
 Wants=gnome-session-restart-dbus.service
 Before=gnome-session-restart-dbus.service
+
+Wants=gnome-session-cleanup-wayland.service
+Before=gnome-session-cleanup-wayland.service
diff --git a/data/meson.build b/data/meson.build
index e02b80d39..180f6f343 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -123,6 +123,7 @@ if enable_systemd_session
   systemd_service = ['gnome-session-manager@.service',
                      'gnome-session-signal-init.service',
                      'gnome-session-restart-dbus.service',
+                     'gnome-session-cleanup-wayland.service',
                      'gnome-session-monitor.service',
                      'gnome-session-failed.service']
 
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index 6839a02df..aede6b905 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -1000,6 +1000,29 @@ do_phase_exit (GsmManager *manager)
                                    NULL);
         }
 
+        /* Delete the wayland socket as defined by WAYLAND_DISPLAY, on systemd
+         * we have a unit taking care of this. */
+        if (!manager->priv->systemd_managed) {
+                const char *wayland_display;
+                int r;
+
+                wayland_display = g_getenv ("WAYLAND_DISPLAY");
+                if (wayland_display) {
+                        const char *runtime_dir;
+
+                        if (g_path_is_absolute (wayland_display)) {
+                                r = g_unlink (wayland_display);
+                        } else {
+                                g_autofree char *path;
+                                runtime_dir = g_get_user_runtime_dir ();
+                                path = g_build_path (runtime_dir, wayland_display, NULL);
+                                r = g_unlink (path);
+                        }
+                        if (r < 0 && errno != ENOENT)
+                                g_warning ("Failed to unlink wayland socket: %d", errno);
+                }
+        }
+
 #ifdef HAVE_SYSTEMD
         if (!manager->priv->systemd_managed)
                 maybe_restart_user_bus (manager);
diff --git a/tools/gnome-session-ctl.c b/tools/gnome-session-ctl.c
index 8d94f8447..1dbea7a83 100644
--- a/tools/gnome-session-ctl.c
+++ b/tools/gnome-session-ctl.c
@@ -140,6 +140,56 @@ do_restart_dbus (void)
                            error->message);
 }
 
+static void
+do_cleanup_wayland (void)
+{
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GVariant) reply = NULL;
+        g_autoptr(GError) error = NULL;
+        const char *unset_envs[] = {
+                "WAYLAND_DISPLAY",
+        };
+        const char *wayland_display;
+        int r;
+
+        /* Delete the wayland socket as defined by WAYLAND_DISPLAY */
+        wayland_display = g_getenv ("WAYLAND_DISPLAY");
+        if (wayland_display) {
+                const char *runtime_dir;
+
+                if (g_path_is_absolute (wayland_display)) {
+                        r = g_unlink (wayland_display);
+                } else {
+                        g_autofree char *path;
+                        runtime_dir = g_get_user_runtime_dir ();
+                        path = g_build_path (runtime_dir, wayland_display, NULL);
+                        r = g_unlink (path);
+                }
+                if (r < 0 && errno != ENOENT)
+                        g_warning ("Failed to unlink wayland socket: %d", errno);
+        }
+
+        connection = get_session_bus ();
+        if (connection == NULL)
+                return;
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             SYSTEMD_DBUS,
+                                             SYSTEMD_PATH_DBUS,
+                                             SYSTEMD_INTERFACE_DBUS,
+                                             "UnsetEnvironment",
+                                             g_variant_new ("(@as)",
+                                                            g_variant_new_strv (unset_envs,
+                                                                                G_N_ELEMENTS (unset_envs))),
+                                             NULL,
+                                             G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                             -1, NULL, &error);
+
+        if (error != NULL)
+                g_warning ("Failed to restart DBus service: %s",
+                           error->message);
+}
+
 typedef struct {
         GMainLoop *loop;
         gint fifo_fd;
@@ -239,6 +289,7 @@ main (int argc, char *argv[])
         static gboolean   opt_signal_init;
         static gboolean   opt_restart_dbus;
         static gboolean   opt_exec_stop_check;
+        static gboolean   opt_cleanup_wayland;
         int     conflicting_options;
         GOptionContext *ctx;
         static const GOptionEntry options[] = {
@@ -246,6 +297,7 @@ main (int argc, char *argv[])
                 { "monitor", '\0', 0, G_OPTION_ARG_NONE, &opt_monitor, N_("Start 
gnome-session-shutdown.target when receiving EOF or a single byte on stdin"), NULL },
                 { "signal-init", '\0', 0, G_OPTION_ARG_NONE, &opt_signal_init, N_("Signal initialization 
done to gnome-session"), NULL },
                 { "restart-dbus", '\0', 0, G_OPTION_ARG_NONE, &opt_restart_dbus, N_("Restart dbus.service if 
it is running"), NULL },
+                { "cleanup-wayland", '\0', 0, G_OPTION_ARG_NONE, &opt_cleanup_wayland, N_("Remove wayland 
socket and WAYLAND_DISPLAY"), NULL },
                 { "exec-stop-check", '\0', 0, G_OPTION_ARG_NONE, &opt_exec_stop_check, N_("Run from 
ExecStopPost to start gnome-session-failed.target on service failure"), NULL },
                 { NULL },
         };
@@ -273,6 +325,8 @@ main (int argc, char *argv[])
                 conflicting_options++;
         if (opt_restart_dbus)
                 conflicting_options++;
+        if (opt_cleanup_wayland)
+                conflicting_options++;
         if (opt_exec_stop_check)
                 conflicting_options++;
         if (conflicting_options != 1) {
@@ -286,6 +340,8 @@ main (int argc, char *argv[])
                 do_signal_init ();
         } else if (opt_restart_dbus) {
                 do_restart_dbus ();
+        } else if (opt_cleanup_wayland) {
+                do_cleanup_wayland ();
         } else if (opt_shutdown) {
                 do_start_unit ("gnome-session-shutdown.target", "replace-irreversibly");
         } else if (opt_monitor) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]