aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/src/XlibInt.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/lib/src/XlibInt.c')
-rw-r--r--nx-X11/lib/src/XlibInt.c109
1 files changed, 89 insertions, 20 deletions
diff --git a/nx-X11/lib/src/XlibInt.c b/nx-X11/lib/src/XlibInt.c
index bd97ed0bc..491213aeb 100644
--- a/nx-X11/lib/src/XlibInt.c
+++ b/nx-X11/lib/src/XlibInt.c
@@ -64,6 +64,7 @@ from The Open Group.
#endif
#include "Xlibint.h"
#include "Xprivate.h"
+#include "reallocarray.h"
#include <nx-X11/Xpoll.h>
#if !USE_XCB
#include <nx-X11/Xtrans/Xtrans.h>
@@ -75,9 +76,28 @@ from The Open Group.
#include <direct.h>
#endif
+/* Needed for FIONREAD on Solaris */
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+/* Needed for FIONREAD on Cygwin */
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+/* Needed for ioctl() on Solaris */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#ifdef XTHREADS
#include "locking.h"
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
/* these pointers get initialized by XInitThreads */
LockInfoPtr _Xglobal_lock = NULL;
void (*_XCreateMutex_fn)(LockInfoPtr) = NULL;
@@ -838,7 +858,7 @@ _XWaitForReadable(
static int sync_hazard(Display *dpy)
{
/*
- * "span" and "hazard" need to be signed such that the ">=" comparision
+ * "span" and "hazard" need to be signed such that the ">=" comparison
* works correctly in the case that hazard is greater than 65525
*/
int64_t span = X_DPY_GET_REQUEST(dpy) - X_DPY_GET_LAST_REQUEST_READ(dpy);
@@ -1625,7 +1645,7 @@ int _XRead(
#ifdef LONG64
void _XRead32(
Display *dpy,
- register long *data,
+ long *data,
long len)
{
register int *buf;
@@ -2477,7 +2497,7 @@ _XRegisterInternalConnection(
new_conni = Xmalloc(sizeof(struct _XConnectionInfo));
if (!new_conni)
return 0;
- new_conni->watch_data = Xmalloc(dpy->watcher_count * sizeof(XPointer));
+ new_conni->watch_data = Xmallocarray(dpy->watcher_count, sizeof(XPointer));
if (!new_conni->watch_data) {
Xfree(new_conni);
return 0;
@@ -2569,7 +2589,7 @@ XInternalConnectionNumbers(
count = 0;
for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next)
count++;
- fd_list = Xmalloc (count * sizeof(int));
+ fd_list = Xmallocarray (count, sizeof(int));
if (!fd_list) {
UnlockDisplay(dpy);
return 0;
@@ -2662,8 +2682,8 @@ XAddConnectionWatch(
/* allocate new watch data */
for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- wd_array = Xrealloc(info_list->watch_data,
- (dpy->watcher_count + 1) * sizeof(XPointer));
+ wd_array = Xreallocarray(info_list->watch_data,
+ dpy->watcher_count + 1, sizeof(XPointer));
if (!wd_array) {
UnlockDisplay(dpy);
return 0;
@@ -2835,11 +2855,10 @@ _XFreeEventCookies(Display *dpy)
head = (struct stored_event**)&dpy->cookiejar;
DL_FOREACH_SAFE(*head, e, tmp) {
- if (dpy->cookiejar == e)
- dpy->cookiejar = NULL;
XFree(e->ev.data);
XFree(e);
}
+ dpy->cookiejar = NULL;
}
/**
@@ -2861,6 +2880,7 @@ _XStoreEventCookie(Display *dpy, XEvent *event)
if (!add) {
ESET(ENOMEM);
_XIOError(dpy);
+ return;
}
add->ev = *cookie;
DL_APPEND(*head, add);
@@ -2934,10 +2954,8 @@ void _XEnq(
else if ((qelt = Xmalloc(sizeof(_XQEvent))) == NULL) {
/* Malloc call failed! */
ESET(ENOMEM);
- _XIOError(dpy);
-#ifdef NX_TRANS_SOCKET
- return;
-#endif
+ _XIOError(dpy);
+ return;
}
qelt->next = NULL;
@@ -3441,18 +3459,51 @@ _XWireToEvent(
return(True);
}
+static int
+SocketBytesReadable(Display *dpy)
+{
+ int bytes = 0, last_error;
+#ifdef WIN32
+ last_error = WSAGetLastError();
+ ioctlsocket(ConnectionNumber(dpy), FIONREAD, &bytes);
+ WSASetLastError(last_error);
+#else
+ last_error = errno;
+ ioctl(ConnectionNumber(dpy), FIONREAD, &bytes);
+ errno = last_error;
+#endif
+ return bytes;
+}
+
+_X_NORETURN void _XDefaultIOErrorExit(
+ Display *dpy,
+ void *user_data)
+{
+ exit(1);
+ /*NOTREACHED*/
+}
/*
* _XDefaultIOError - Default fatal system error reporting routine. Called
* when an X internal system error is encountered.
*/
-int _XDefaultIOError(
+_X_NORETURN int _XDefaultIOError(
Display *dpy)
{
- if (ECHECK(EPIPE)) {
- (void) fprintf (stderr,
- "X connection to %s broken (explicit kill or server shutdown).\r\n",
- DisplayString (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));
} else {
(void) fprintf (stderr,
"XIO: fatal IO error %d (%s) on X server \"%s\"\r\n",
@@ -3666,6 +3717,11 @@ int _XError (
if (_XErrorFunction != NULL) {
int rtn_val;
#ifdef XTHREADS
+ struct _XErrorThreadInfo thread_info = {
+ .error_thread = xthread_self(),
+ .next = dpy->error_threads
+ }, **prev;
+ dpy->error_threads = &thread_info;
if (dpy->lock)
(*dpy->lock->user_lock_display)(dpy);
UnlockDisplay(dpy);
@@ -3675,6 +3731,11 @@ int _XError (
LockDisplay(dpy);
if (dpy->lock)
(*dpy->lock->user_unlock_display)(dpy);
+
+ /* unlink thread_info from the list */
+ for (prev = &dpy->error_threads; *prev != &thread_info; prev = &(*prev)->next)
+ ;
+ *prev = thread_info.next;
#endif
return rtn_val;
} else {
@@ -3689,6 +3750,9 @@ int
_XIOError (
Display *dpy)
{
+ XIOErrorExitHandler exit_handler;
+ void *exit_handler_data;
+
dpy->flags |= XlibDisplayIOError;
#ifdef WIN32
errno = WSAGetLastError();
@@ -3702,6 +3766,8 @@ _XIOError (
if (dpy->lock)
(*dpy->lock->user_lock_display)(dpy);
#endif
+ exit_handler = dpy->exit_handler;
+ exit_handler_data = dpy->exit_handler_data;
UnlockDisplay(dpy);
if (_XIOErrorFunction != NULL)
@@ -3721,6 +3787,7 @@ _XIOError (
#ifdef NX_TRANS_EXIT
NXTransExit(1);
#else
+ exit_handler(dpy, exit_handler_data);
exit(1);
#endif
}
@@ -3749,6 +3816,7 @@ _XIOError (
/* shut up the compiler by returning something */
return 0;
#else
+ exit_handler(dpy, exit_handler_data);
exit (1);
#endif
/*NOTREACHED*/
@@ -3932,9 +4000,9 @@ int _XGetHostname (
return 0;
uname (&name);
- len = strlen (name.nodename);
+ len = (int) strlen (name.nodename);
if (len >= maxlen) len = maxlen - 1;
- strncpy (buf, name.nodename, len);
+ strncpy (buf, name.nodename, (size_t) len);
buf[len] = '\0';
#else
if (maxlen <= 0 || buf == NULL)
@@ -3943,7 +4011,7 @@ int _XGetHostname (
buf[0] = '\0';
(void) gethostname (buf, maxlen);
buf [maxlen - 1] = '\0';
- len = strlen(buf);
+ len = (int) strlen(buf);
#endif /* NEED_UTSNAME */
return len;
}
@@ -3972,6 +4040,7 @@ Screen *_XScreenOfWindow(Display *dpy, Window w)
return NULL;
}
+
/*
* WARNING: This implementation's pre-conditions and post-conditions
* must remain compatible with the old macro-based implementations of