diff options
author | Tudor Brindus <me@tbrindus.ca> | 2020-10-12 23:47:29 -0400 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2020-10-13 09:02:20 +0200 |
commit | afeb941ca027995530d940b81f28421456c77640 (patch) | |
tree | 47cd93ed11f7ffe0d92ced6c51a3e771505d2b0c | |
parent | 7bb9d48dd1383b688c8fefbbb08c552c3cc33c18 (diff) |
xwayland: notify requestor when we fail to respond to their request
We already mostly did this, but there were a couple of branches
(`calloc` failures) where we'd bail without letting the other side know.
Refs swaywm/sway#4007. Likely not going to be a real improvement there
(if `calloc` fails you're already pretty screwed), but it does address a
theoretical possibility.
-rw-r--r-- | xwayland/selection/outgoing.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/xwayland/selection/outgoing.c b/xwayland/selection/outgoing.c index 190fb741..a5ce2fd2 100644 --- a/xwayland/selection/outgoing.c +++ b/xwayland/selection/outgoing.c @@ -265,15 +265,14 @@ static struct wl_array *xwm_selection_source_get_mime_types( /** * Read the Wayland selection and send it to an Xwayland client. */ -static void xwm_selection_send_data(struct wlr_xwm_selection *selection, +static bool xwm_selection_send_data(struct wlr_xwm_selection *selection, xcb_selection_request_event_t *req, const char *mime_type) { // Check MIME type struct wl_array *mime_types = xwm_selection_source_get_mime_types(selection); if (mime_types == NULL) { wlr_log(WLR_ERROR, "not sending selection: no MIME type list available"); - xwm_selection_send_notify(selection->xwm, req, false); - return; + return false; } bool found = false; @@ -288,16 +287,16 @@ static void xwm_selection_send_data(struct wlr_xwm_selection *selection, if (!found) { wlr_log(WLR_ERROR, "not sending selection: " "requested an unsupported MIME type %s", mime_type); - xwm_selection_send_notify(selection->xwm, req, false); - return; + return false; } struct wlr_xwm_selection_transfer *transfer = calloc(1, sizeof(struct wlr_xwm_selection_transfer)); if (transfer == NULL) { wlr_log(WLR_ERROR, "Allocation failed"); - return; + return false; } + transfer->selection = selection; transfer->request = *req; wl_array_init(&transfer->source_data); @@ -305,9 +304,9 @@ static void xwm_selection_send_data(struct wlr_xwm_selection *selection, int p[2]; if (pipe(p) == -1) { wlr_log_errno(WLR_ERROR, "pipe() failed"); - xwm_selection_send_notify(selection->xwm, req, false); - return; + return false; } + fcntl(p[0], F_SETFD, FD_CLOEXEC); fcntl(p[0], F_SETFL, O_NONBLOCK); fcntl(p[1], F_SETFD, FD_CLOEXEC); @@ -345,6 +344,8 @@ static void xwm_selection_send_data(struct wlr_xwm_selection *selection, wlr_log(WLR_DEBUG, "Transfer %p still queued", outgoing); } } + + return true; } static void xwm_selection_send_targets(struct wlr_xwm_selection *selection, @@ -416,12 +417,12 @@ void xwm_handle_selection_request(struct wlr_xwm *xwm, xwm_get_selection(xwm, req->selection); if (selection == NULL) { wlr_log(WLR_DEBUG, "received selection request for unknown selection"); - return; + goto fail_notify_requestor; } if (selection->window != req->owner) { wlr_log(WLR_DEBUG, "received selection request with invalid owner"); - return; + goto fail_notify_requestor; } // No xwayland surface focused, deny access to clipboard @@ -430,8 +431,7 @@ void xwm_handle_selection_request(struct wlr_xwm *xwm, wlr_log(WLR_DEBUG, "denying read access to selection %u (%s): " "no xwayland surface focused", selection->atom, selection_name); free(selection_name); - xwm_selection_send_notify(xwm, req, false); - return; + goto fail_notify_requestor; } if (req->target == xwm->atoms[TARGETS]) { @@ -446,12 +446,22 @@ void xwm_handle_selection_request(struct wlr_xwm *xwm, if (mime_type == NULL) { wlr_log(WLR_ERROR, "ignoring selection request: unknown atom %u", req->target); - xwm_selection_send_notify(xwm, req, false); - return; + goto fail_notify_requestor; } - xwm_selection_send_data(selection, req, mime_type); + + bool send_success = xwm_selection_send_data(selection, req, mime_type); free(mime_type); + if (!send_success) { + goto fail_notify_requestor; + } } + + return; + +fail_notify_requestor: + // Something went wrong, and there won't be any data being sent to the + // requestor, so let them know. + xwm_selection_send_notify(xwm, req, false); } void xwm_handle_selection_destroy_notify(struct wlr_xwm *xwm, |