[comp.bugs.misc] XV11R2 and Sun 4.2 Release 3.5 don't mix

ado@elsie.UUCP (07/12/88)

VERSION:
	X11 release 2

CLIENT MACHINE:
	Sun 3/160

CLIENT OPERATING SYSTEM:
	Sun UNIX 4.2 Release 3.5

DISPLAY:
	Sun B&W

SYNOPSIS:
	Clients can terminate abnormally (and erroneously) if the server
	falls behind.

DESCRIPTION:
	The problem comes about when the socket buffer fills up (at the 4096
	character mark on an as-shipped 3.5 system).  When this happens,
	writes to the socket return EMSGSIZE in errno (rather than,
	for example, EWOULDBLOCK). 
	The function in XlibInt.c that handles output notices the EMSGSIZE
	error and gets into a loop where it halves the write size each time
	through.  When the write size drops to zero, errno is set to EINVAL
	and the client punts.

REPEAT-BY:
	Compile and run the attached code from xterm with uwm running,
	then tap RETURN in the xterm window after you've opened the window.
	Note the "XIO: Invalid argument" message.
	(Since the appearance of the message depends on whether the server
	keeps up with write requests, it's somewhat nondeterministic.
	If the message does not appear, just tap RETURN a second time, then
	load up the server with some superfluous windows and try again.)

	#include "stdio.h"
	#include "X11/Xlib.h"

	#define NBPC	8
	#define WIDTH	500
	#define HEIGHT	500

	char	data[HEIGHT][WIDTH / NBPC];

	main()
	{
		Display *	display;
		Window		window;
		GC		gc;
		Visual *	visual;
		int		y, x;
		XImage *	ximage;

		for (y = 0; y < HEIGHT; ++y)
			for (x = 0; x < sizeof data[y]; ++x)
				data[y][x] = x + y;
		display = XOpenDisplay((char *) NULL);
		XSynchronize(display, 1);
		window = XCreateSimpleWindow(display, RootWindow(display, 0),
			0, 0, WIDTH, HEIGHT, 5, 1, 0);
		XMapWindow(display, window);
		(void) getchar();
		gc = DefaultGC(display, 0);
		visual = DefaultVisual(display, 0);
		ximage = XCreateImage(display, visual, 1, XYBitmap, 0, data,
			WIDTH, HEIGHT, NBPC, 0);
		(void) XPutImage(display, window, gc, ximage,
			0, 0, 0, 0, WIDTH, HEIGHT);
		(void) getchar();
		return 0;
	}

FIX:
	I don't know if Sun's 4.0 changes what errno gets set to; in any event,
	a workaround in the X library is useful for Sun 3.5 binary sites
	(like ours).  We'll assume that if a message of size 1 fails with an
	EMSGSIZE error, we're on a system that sometimes gives inappropriate
	EMSGSIZE errors.

	*** lib/X/XlibInt.c	Tue Jul 12 09:59:36 1988
	--- lib/X/XlibInt.c	Tue Jul 12 09:59:40 1988
	***************
	*** 310,316 ****
	--- 310,323 ----
	  #endif
	  #ifdef EMSGSIZE
		    } else if (errno == EMSGSIZE) {
	+ #ifdef ASWAS
			todo = todo >> 1;
	+ #else /* !defined ASWAS */
	+ 		if (todo == 1) {
	+ 			_XWaitForWritable(dpy);
	+ 			todo = total;
	+ 		} else 	todo = todo >> 1;
	+ #endif /* !defined ASWAS */
	  #endif
		    } else {
			(*_XIOErrorFunction)(dpy);
-- 
	ado@ncifcrf.gov			ADO is a trademark of Ampex.