From 1fc0a26c9cc5b0771ea1fbab34b177e5b151627e Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 11 Dec 2020 14:19:29 +0100 Subject: 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(+) create mode 100644 data/gnome-session-cleanup-wayland.service.in diff --git a/data/gnome-session-cleanup-wayland.service.in b/data/gnome-session-cleanup-wayland.service.in new file mode 100644 index 00000000..8e70da01 --- /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 2c3d1963..4c3183eb 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 e02b80d3..180f6f34 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 6839a02d..aede6b90 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 8d94f844..1dbea7a8 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) { -- cgit v1.2.1