|
|
4bb429 |
From 5538b3e4ae6dee32c47db9dfc85b07bbe7b90f6c Mon Sep 17 00:00:00 2001
|
|
|
4bb429 |
From: Adam Jackson <ajax@redhat.com>
|
|
|
4bb429 |
Date: Fri, 24 Mar 2017 11:07:36 -0400
|
|
|
4bb429 |
Subject: [PATCH 2/2] _XDefaultIOError: Do better at detecting explicit
|
|
|
4bb429 |
shutdown
|
|
|
4bb429 |
|
|
|
4bb429 |
Currently, when the X server crashes or a client is disconnected with
|
|
|
4bb429 |
XKillClient, you get a somewhat confusing error message from libX11
|
|
|
4bb429 |
along the lines of:
|
|
|
4bb429 |
|
|
|
4bb429 |
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
|
|
|
4bb429 |
after 98 requests (40 known processed) with 0 events remaining.
|
|
|
4bb429 |
|
|
|
4bb429 |
What's happening here is the previous recvmsg has thrown EAGAIN, since
|
|
|
4bb429 |
the socket is non-blocking. In this case, check whether the socket has
|
|
|
4bb429 |
any more data to read, and if not treat it like EPIPE.
|
|
|
4bb429 |
|
|
|
4bb429 |
Signed-off-by: Adam Jackson <ajax@redhat.com>
|
|
|
4bb429 |
---
|
|
|
4bb429 |
src/XlibInt.c | 29 ++++++++++++++++++++++++++++-
|
|
|
4bb429 |
1 file changed, 28 insertions(+), 1 deletion(-)
|
|
|
4bb429 |
|
|
|
4bb429 |
diff --git a/src/XlibInt.c b/src/XlibInt.c
|
|
|
4bb429 |
index 903e47f3..dd39445b 100644
|
|
|
4bb429 |
--- a/src/XlibInt.c
|
|
|
4bb429 |
+++ b/src/XlibInt.c
|
|
|
4bb429 |
@@ -50,6 +50,8 @@ from The Open Group.
|
|
|
4bb429 |
#ifdef XTHREADS
|
|
|
4bb429 |
#include "locking.h"
|
|
|
4bb429 |
|
|
|
4bb429 |
+#include <sys/ioctl.h>
|
|
|
4bb429 |
+
|
|
|
4bb429 |
/* these pointers get initialized by XInitThreads */
|
|
|
4bb429 |
LockInfoPtr _Xglobal_lock = NULL;
|
|
|
4bb429 |
void (*_XCreateMutex_fn)(LockInfoPtr) = NULL;
|
|
|
4bb429 |
@@ -1234,6 +1236,21 @@ _XWireToEvent(
|
|
|
4bb429 |
return(True);
|
|
|
4bb429 |
}
|
|
|
4bb429 |
|
|
|
4bb429 |
+static int
|
|
|
4bb429 |
+SocketBytesReadable(Display *dpy)
|
|
|
4bb429 |
+{
|
|
|
4bb429 |
+ int bytes = 0, last_error;
|
|
|
4bb429 |
+#ifdef WIN32
|
|
|
4bb429 |
+ last_error = WSAGetLastError();
|
|
|
4bb429 |
+ ioctlsocket(ConnectionNumber(dpy), FIONREAD, &bytes);
|
|
|
4bb429 |
+ WSASetLastError(last_error);
|
|
|
4bb429 |
+#else
|
|
|
4bb429 |
+ last_error = errno;
|
|
|
4bb429 |
+ ioctl(ConnectionNumber(dpy), FIONREAD, &bytes);
|
|
|
4bb429 |
+ errno = last_error;
|
|
|
4bb429 |
+#endif
|
|
|
4bb429 |
+ return bytes;
|
|
|
4bb429 |
+}
|
|
|
4bb429 |
|
|
|
4bb429 |
/*
|
|
|
4bb429 |
* _XDefaultIOError - Default fatal system error reporting routine. Called
|
|
|
4bb429 |
@@ -1242,7 +1259,17 @@ _XWireToEvent(
|
|
|
4bb429 |
_X_NORETURN int _XDefaultIOError(
|
|
|
4bb429 |
Display *dpy)
|
|
|
4bb429 |
{
|
|
|
4bb429 |
- if (ECHECK(EPIPE)) {
|
|
|
4bb429 |
+ int killed = ECHECK(EPIPE);
|
|
|
4bb429 |
+
|
|
|
4bb429 |
+ /*
|
|
|
4bb429 |
+ * If the socket was closed on the far end, the final recvmsg in
|
|
|
4bb429 |
+ * xcb will have thrown EAGAIN because we're non-blocking. Detect
|
|
|
4bb429 |
+ * this to get the more informative error message.
|
|
|
4bb429 |
+ */
|
|
|
4bb429 |
+ if (ECHECK(EAGAIN) && SocketBytesReadable(dpy) <= 0)
|
|
|
4bb429 |
+ killed = True;
|
|
|
4bb429 |
+
|
|
|
4bb429 |
+ if (killed) {
|
|
|
4bb429 |
fprintf (stderr,
|
|
|
4bb429 |
"X connection to %s broken (explicit kill or server shutdown).\r\n",
|
|
|
4bb429 |
DisplayString (dpy));
|
|
|
4bb429 |
--
|
|
|
4bb429 |
2.21.0
|
|
|
4bb429 |
|