From 3f10857496e1027af3740d374b749fa5d58c0010 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:43:46 +0200 Subject: [PATCH] Fix pid lookup for the Kill action Before this patch, labwc would happily kill itself when the user called the `Kill` action when any xwayland view had focus. The reason this happened was that wlroots creates the xwayland wayland client via socketpair() and thus a lookup of the pid of the socket connection would return the pid of labwc itself. This patch fixes that by implementing different pid lookup mechanisms based on the view implementation backend. Fixes: #1739 --- include/view.h | 2 ++ src/action.c | 11 ++++++----- src/xdg.c | 15 +++++++++++++++ src/xwayland.c | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/include/view.h b/include/view.h index 0cc3cfbd..182a28b8 100644 --- a/include/view.h +++ b/include/view.h @@ -135,6 +135,8 @@ struct view_impl { bool (*has_strut_partial)(struct view *self); /* returns true if view declared itself a window type */ bool (*contains_window_type)(struct view *view, int32_t window_type); + /* returns the client pid that this view belongs to */ + pid_t (*get_pid)(struct view *view); }; struct view { diff --git a/src/action.c b/src/action.c index 7cc4bc56..bf94e0a0 100644 --- a/src/action.c +++ b/src/action.c @@ -691,12 +691,13 @@ actions_run(struct view *activator, struct server *server, } break; case ACTION_TYPE_KILL: - if (view && view->surface) { + if (view) { /* Send SIGTERM to the process associated with the surface */ - pid_t pid = -1; - struct wl_client *client = view->surface->resource->client; - wl_client_get_credentials(client, &pid, NULL, NULL); - if (pid != -1) { + assert(view->impl->get_pid); + pid_t pid = view->impl->get_pid(view); + if (pid == getpid()) { + wlr_log(WLR_ERROR, "Preventing sending SIGTERM to labwc"); + } else if (pid > 0) { kill(pid, SIGTERM); } } diff --git a/src/xdg.c b/src/xdg.c index 154eb34f..78c549b0 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -659,6 +659,20 @@ xdg_toplevel_view_unmap(struct view *view, bool client_request) } } +static pid_t +xdg_view_get_pid(struct view *view) +{ + assert(view); + pid_t pid = -1; + + if (view->surface && view->surface->resource + && view->surface->resource->client) { + struct wl_client *client = view->surface->resource->client; + wl_client_get_credentials(client, &pid, NULL, NULL); + } + return pid; +} + static const struct view_impl xdg_toplevel_view_impl = { .configure = xdg_toplevel_view_configure, .close = xdg_toplevel_view_close, @@ -675,6 +689,7 @@ static const struct view_impl xdg_toplevel_view_impl = { .get_root = xdg_toplevel_view_get_root, .append_children = xdg_toplevel_view_append_children, .contains_window_type = xdg_toplevel_view_contains_window_type, + .get_pid = xdg_view_get_pid, }; static void diff --git a/src/xwayland.c b/src/xwayland.c index 58d61a80..3a936456 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -838,6 +838,19 @@ xwayland_view_set_fullscreen(struct view *view, bool fullscreen) fullscreen); } +static pid_t +xwayland_view_get_pid(struct view *view) +{ + assert(view); + + struct wlr_xwayland_surface *xwayland_surface = + xwayland_surface_from_view(view); + if (!xwayland_surface) { + return -1; + } + return xwayland_surface->pid; +} + static const struct view_impl xwayland_view_impl = { .configure = xwayland_view_configure, .close = xwayland_view_close, @@ -856,6 +869,7 @@ static const struct view_impl xwayland_view_impl = { .wants_focus = xwayland_view_wants_focus, .has_strut_partial = xwayland_view_has_strut_partial, .contains_window_type = xwayland_view_contains_window_type, + .get_pid = xwayland_view_get_pid, }; void