diff options
Diffstat (limited to 'nx-X11/lib/src/XlibInt.c')
-rw-r--r-- | nx-X11/lib/src/XlibInt.c | 109 |
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 |