lmjm@doc.imperial.ac.UK (04/11/89)
I too had xterm occasionally keeling over and xlsfonts not replying
with the full list. Here are the patches which worked for me, I
posted both to xbugs but since it seems to be a manufacturer specific
thing as to wether you have these problems I guess these patches won't
become standard.
The problems seem to be in how sockets (and in particular unix domain
sockets) are implemented.
Please read the comments below.
Hope these help.
From lmjm@doc.ic.ac.uk Fri Jan 27 22:24:15 1989
From: Lee McLoughlin <lmjm@doc.ic.ac.uk>
Date: Fri, 13 Jan 89 22:40:10 GMT
To: xbugs <@nss.css.ucl.ac.uk:xbugs@expo.lcs.mit.edu>
Cc: lmjm@doc.ic.ac.uk
Subject: X.V11R3 bug report
X Window System Bug Report
xbugs@expo.lcs.mit.edu
VERSION:
R3
CLIENT MACHINE and OPERATING SYSTEM:
HLH Clipper Orion running 4.2 BSD
DISPLAY:
HLH StarPoint
[Digital QVSS, Sun CG4, HP Topcat, IBM APA16, Apollo 4 plane, ...]
WINDOW MANAGER:
awm
AREA:
Xlib (xterm)
SYNOPSIS:
xterm using a Unix domain socket will quit unexpectedly when
listing long files.
DESCRIPTION:
Xlib in XlibInt.c in the routine _XSend() somehow ends up passing a
0 as the third arg to WritevToServer(). This causes the writev() then
to fail with an EINVAL error. After detailed tracing of the code
I have no idea why this occurs. It only happens with Unix domain
sockets - not with TCP sockets.
REPEAT BY:
setenv DISPLAY unix:0
xterm
in the xterm window turn on jump scroll
then do "cat /etc/termcap"
after 3 pages or so xterm will quit with an error message of:
xterm: invalid arg
SAMPLE FIX:
Since it can never reach the WritevToServer() without having
something to write and that would have to be in iov I just ensure
i is at least one.
*** XlibInt.c.orig Thu Jan 12 23:19:54 1989
--- XlibInt.c Fri Jan 13 22:39:40 1989
***************
*** 495,500 ****
--- 495,505 ----
InsertIOV(pad, padlength[size & 3])
errno = 0;
+
+ /* Always using at least iov[ 0 ] */
+ if (i == 0)
+ i = 1;
+
if ((len = WritevToServer(dpy->fd, iov, i)) >= 0) {
skip += len;
total -= len;
------------------------------------------------------------------------------
From lmjm@doc.ic.ac.uk Fri Jan 27 22:27:06 1989
From: Lee McLoughlin <lmjm@doc.ic.ac.uk>
Date: Mon, 16 Jan 89 20:55:55 GMT
To: xbugs <@nss.cs.ucl.ac.uk:xbugs@expo.lcs.mit.edu>
Cc: lmjm@doc.ic.ac.uk
Subject: X.V11R3 bug report
X Window System Bug Report
xbugs@expo.lcs.mit.edu
VERSION:
R3
CLIENT MACHINE and OPERATING SYSTEM:
HLH Clipper Orion running 4.2 BSD
DISPLAY:
HLH StarPoint
[Digital QVSS, Sun CG4, HP Topcat, IBM APA16, Apollo 4 plane, ...]
WINDOW MANAGER:
awm
AREA:
X server
SYNOPSIS:
The server fails to write any message greater than 8K back to the client.
DESCRIPTION:
Under 4.2 BSD the max size of a message you can send on a pipe is
8K (at least on the few 4.2 BSD's I could find). In
server/os/4.2bsd/io.c FlushClient() allows blocks of any size to
be written.
REPEAT BY:
With all the core fonts available try:
xlsfonts
This fails with
Connection # 3 to server broken.
XIO: Broken pipe
SAMPLE FIX:
I've made the code #ifdef'd hlh - the machine I wrote it for. It should
really be for any machine with a socket message size limit but I couldn't
find any suitable #define and didn't feel up to adding one - its been
a long day.
*** io.c.old Mon Jan 16 18:19:18 1989
--- io.c Mon Jan 16 20:52:39 1989
***************
*** 314,353 ****
int connection = oc->fd,
total, n, i, notWritten, written,
iovCnt = 0;
struct iovec iov[3];
char padBuffer[3];
total = 0;
if (oc->count)
{
! total += iov[iovCnt].iov_len = oc->count;
! iov[iovCnt++].iov_base = (caddr_t)oc->buf;
/* Notice that padding isn't needed for oc->buf since
it is alreay padded by WriteToClient */
}
if (extraCount)
{
! total += iov[iovCnt].iov_len = extraCount;
! iov[iovCnt++].iov_base = extraBuf;
if (extraCount & 3)
{
! total += iov[iovCnt].iov_len = padlength[extraCount & 3];
! iov[iovCnt++].iov_base = padBuffer;
}
}
notWritten = total;
while ((n = writev (connection, iov, iovCnt)) != notWritten)
{
#ifdef hpux
if (n == -1 && errno == EMSGSIZE)
n = swWritev (connection, iov, 2);
#endif
if (n > 0)
{
notWritten -= n;
for (i = 0; i < iovCnt; i++)
{
if (n > iov[i].iov_len)
{
n -= iov[i].iov_len;
--- 314,406 ----
int connection = oc->fd,
total, n, i, notWritten, written,
iovCnt = 0;
+ #define _AddToIov( bytes, len ) \
+ total += iov[iovCnt].iov_len = (len); \
+ iov[iovCnt++].iov_base = (caddr_t)(bytes);
+ #ifndef hlh
struct iovec iov[3];
+ #define AddToIov(bytes, len) _AddToIov(bytes, len)
+ #else
+ int iovs;
+ struct iovec iov[100]; /* Enough to avoid the need for dynamic allocation */
+ #define MAX_MSG 8192 /* Max size of a single iov to writev */
+ #define AddToIov( bytes, len ) \
+ { \
+ char *buf = bytes; \
+ int towrite = len; \
+ while( towrite > MAX_MSG ){ \
+ _AddToIov( buf, MAX_MSG ); \
+ towrite -= MAX_MSG; \
+ buf += MAX_MSG; \
+ } \
+ _AddToIov( buf, towrite ); \
+ }
+ #endif
char padBuffer[3];
total = 0;
if (oc->count)
{
! AddToIov( oc->buf, oc->count );
/* Notice that padding isn't needed for oc->buf since
it is alreay padded by WriteToClient */
}
if (extraCount)
{
! AddToIov( extraBuf, extraCount );
if (extraCount & 3)
{
! AddToIov( padBuffer, padlength[extraCount & 3] );
}
}
notWritten = total;
+ #ifndef hlh
while ((n = writev (connection, iov, iovCnt)) != notWritten)
+ #else
+ iovs = iovCnt;
+ while ((n = writev (connection, iov, iovs)) != notWritten)
+ #endif
{
#ifdef hpux
if (n == -1 && errno == EMSGSIZE)
n = swWritev (connection, iov, 2);
#endif
+ #ifdef hlh
+ if (n == -1 && errno == EMSGSIZE){
+ /* Too large a lump to write.
+ * try with a fewer iov's.
+ */
+ int siz = 0;
+ struct iovec *ip;
+
+ /* How many iov's are less than the max? */
+ iovs = 0;
+ ip = &iov[0];
+ while( (siz + ip->iov_len) <= MAX_MSG ){
+ siz += ip->iov_len;
+ ip++;
+ iovs++;
+ }
+ continue;
+ }
+ else {
+ /* Once its succeeded then try to write the rest - the
+ * code in the if statement below should prevent iov's from
+ * being resent */
+ iovs = iovCnt;
+ }
+ #endif
if (n > 0)
{
notWritten -= n;
for (i = 0; i < iovCnt; i++)
{
+ #ifdef hlh
+ /* ignore buffers that have been written already */
+ if (iov[i].iov_len == 0 )
+ continue;
+ #endif
if (n > iov[i].iov_len)
{
n -= iov[i].iov_len;
--
Lee McLoughlin 01 589 5111 X 5028
Department of Computing,Imperial College,180 Queens Gate,London SW7 2BZ, UK
Janet: lmjm@uk.ac.ic.doc Uucp: lmjm@icdoc.UUCP, ukc!icdoc!lmjm
DARPA: lmjm@doc.ic.ac.uk (or lmjm%uk.ac.ic.doc@nss.cs.ucl.ac.uk)