Backport all patches to git master for various fixes inc (#1809717)
This commit is contained in:
159
0037-x11-Handle-windowing-errors-while-writing-selection-.patch
Normal file
159
0037-x11-Handle-windowing-errors-while-writing-selection-.patch
Normal file
@@ -0,0 +1,159 @@
|
||||
From 2ecbf6d74637508203290c0e324d736de10a9174 Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Garnacho <carlosg@gnome.org>
|
||||
Date: Mon, 24 Feb 2020 15:33:08 +0100
|
||||
Subject: [PATCH 37/48] x11: Handle windowing errors while writing selection
|
||||
INCR data
|
||||
|
||||
This error was just logged but not raised. Do as the code comment said
|
||||
and raise a pipe error at that moment, and for subsequent operations
|
||||
on the output stream (although none besides close() should be expected
|
||||
after propagating the error properly).
|
||||
|
||||
Related: https://gitlab.gnome.org/GNOME/mutter/issues/1065
|
||||
---
|
||||
src/x11/meta-x11-selection-output-stream.c | 62 +++++++++++++++++++---
|
||||
1 file changed, 56 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/x11/meta-x11-selection-output-stream.c b/src/x11/meta-x11-selection-output-stream.c
|
||||
index 1883bc92a..f51dbc4c3 100644
|
||||
--- a/src/x11/meta-x11-selection-output-stream.c
|
||||
+++ b/src/x11/meta-x11-selection-output-stream.c
|
||||
@@ -53,6 +53,7 @@ struct _MetaX11SelectionOutputStreamPrivate
|
||||
|
||||
guint incr : 1;
|
||||
guint delete_pending : 1;
|
||||
+ guint pipe_error : 1;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaX11SelectionOutputStream,
|
||||
@@ -167,6 +168,25 @@ get_element_size (int format)
|
||||
}
|
||||
}
|
||||
|
||||
+static gboolean
|
||||
+meta_x11_selection_output_stream_check_pipe (MetaX11SelectionOutputStream *stream,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ MetaX11SelectionOutputStreamPrivate *priv =
|
||||
+ meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
+
|
||||
+ if (priv->pipe_error)
|
||||
+ {
|
||||
+ g_set_error (error,
|
||||
+ G_IO_ERROR,
|
||||
+ G_IO_ERROR_BROKEN_PIPE,
|
||||
+ "Connection with client was broken");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *stream)
|
||||
{
|
||||
@@ -174,6 +194,7 @@ meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *st
|
||||
meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
Display *xdisplay;
|
||||
size_t element_size, n_elements;
|
||||
+ int error_code;
|
||||
|
||||
g_assert (!priv->delete_pending);
|
||||
|
||||
@@ -230,18 +251,28 @@ meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *st
|
||||
g_cond_broadcast (&priv->cond);
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
|
||||
- /* XXX: handle failure here and report EPIPE for future operations on the stream? */
|
||||
- if (meta_x11_error_trap_pop_with_return (priv->x11_display))
|
||||
- g_warning ("Failed to flush selection output stream");
|
||||
+ error_code = meta_x11_error_trap_pop_with_return (priv->x11_display);
|
||||
|
||||
- if (priv->pending_task)
|
||||
+ if (error_code != Success)
|
||||
+ {
|
||||
+ char error_str[100];
|
||||
+
|
||||
+ XGetErrorText (xdisplay, error_code, error_str, sizeof (error_str));
|
||||
+ g_task_return_new_error (priv->pending_task,
|
||||
+ G_IO_ERROR,
|
||||
+ G_IO_ERROR_BROKEN_PIPE,
|
||||
+ "Failed to flush selection output stream: %s",
|
||||
+ error_str);
|
||||
+ g_clear_object (&priv->pending_task);
|
||||
+ priv->pipe_error = TRUE;
|
||||
+ }
|
||||
+ else if (priv->pending_task)
|
||||
{
|
||||
size_t result;
|
||||
|
||||
result = GPOINTER_TO_SIZE (g_task_get_task_data (priv->pending_task));
|
||||
g_task_return_int (priv->pending_task, result);
|
||||
- g_object_unref (priv->pending_task);
|
||||
- priv->pending_task = NULL;
|
||||
+ g_clear_object (&priv->pending_task);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +301,9 @@ meta_x11_selection_output_stream_write (GOutputStream *output_stream,
|
||||
MetaX11SelectionOutputStreamPrivate *priv =
|
||||
meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
|
||||
+ if (!meta_x11_selection_output_stream_check_pipe (stream, error))
|
||||
+ return -1;
|
||||
+
|
||||
g_mutex_lock (&priv->mutex);
|
||||
g_byte_array_append (priv->data, buffer, count);
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
@@ -297,12 +331,19 @@ meta_x11_selection_output_stream_write_async (GOutputStream *output_stream
|
||||
META_X11_SELECTION_OUTPUT_STREAM (output_stream);
|
||||
MetaX11SelectionOutputStreamPrivate *priv =
|
||||
meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
+ GError *error = NULL;
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (stream, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, meta_x11_selection_output_stream_write_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
+ if (!meta_x11_selection_output_stream_check_pipe (stream, &error))
|
||||
+ {
|
||||
+ g_task_return_error (task, error);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
g_mutex_lock (&priv->mutex);
|
||||
g_byte_array_append (priv->data, buffer, count);
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
@@ -369,6 +410,8 @@ meta_x11_selection_output_stream_flush (GOutputStream *output_stream,
|
||||
MetaX11SelectionOutputStreamPrivate *priv =
|
||||
meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
|
||||
+ if (!meta_x11_selection_output_stream_check_pipe (stream, error))
|
||||
+ return FALSE;
|
||||
if (!meta_x11_selection_output_request_flush (stream))
|
||||
return TRUE;
|
||||
|
||||
@@ -394,12 +437,19 @@ meta_x11_selection_output_stream_flush_async (GOutputStream *output_stream
|
||||
META_X11_SELECTION_OUTPUT_STREAM (output_stream);
|
||||
MetaX11SelectionOutputStreamPrivate *priv =
|
||||
meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
+ GError *error = NULL;
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (stream, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, meta_x11_selection_output_stream_flush_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
+ if (!meta_x11_selection_output_stream_check_pipe (stream, &error))
|
||||
+ {
|
||||
+ g_task_return_error (task, error);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!meta_x11_selection_output_stream_can_flush (stream))
|
||||
{
|
||||
if (meta_x11_selection_output_request_flush (stream))
|
||||
--
|
||||
2.26.0.rc2
|
||||
|
||||
Reference in New Issue
Block a user