Commit 5538b3e4 authored by Adam Jackson's avatar Adam Jackson 🎧

_XDefaultIOError: Do better at detecting explicit shutdown

Currently, when the X server crashes or a client is disconnected with
XKillClient, you get a somewhat confusing error message from libX11
along the lines of:

XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
      after 98 requests (40 known processed) with 0 events remaining.

What's happening here is the previous recvmsg has thrown EAGAIN, since
the socket is non-blocking. In this case, check whether the socket has
any more data to read, and if not treat it like EPIPE.
Signed-off-by: Adam Jackson's avatarAdam Jackson <>
parent 6d2cde96
......@@ -50,6 +50,8 @@ from The Open Group.
#include "locking.h"
#include <sys/ioctl.h>
/* these pointers get initialized by XInitThreads */
LockInfoPtr _Xglobal_lock = NULL;
void (*_XCreateMutex_fn)(LockInfoPtr) = NULL;
......@@ -1234,6 +1236,21 @@ _XWireToEvent(
static int
SocketBytesReadable(Display *dpy)
int bytes = 0, last_error;
#ifdef WIN32
last_error = WSAGetLastError();
ioctlsocket(ConnectionNumber(dpy), FIONREAD, &bytes);
last_error = errno;
ioctl(ConnectionNumber(dpy), FIONREAD, &bytes);
errno = last_error;
return bytes;
* _XDefaultIOError - Default fatal system error reporting routine. Called
......@@ -1242,7 +1259,17 @@ _XWireToEvent(
_X_NORETURN int _XDefaultIOError(
Display *dpy)
int killed = ECHECK(EPIPE);
* If the socket was closed on the far end, the final recvmsg in
* xcb will have thrown EAGAIN because we're non-blocking. Detect
* this to get the more informative error message.
if (ECHECK(EAGAIN) && SocketBytesReadable(dpy) <= 0)
killed = True;
if (killed) {
fprintf (stderr,
"X connection to %s broken (explicit kill or server shutdown).\r\n",
DisplayString (dpy));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment