Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!rutgers!iuvax!pur-ee!uiucdcs!uxc.cso.uiuc.edu!uicsrd!kai From: kai@uicsrd.csrd.uiuc.edu Newsgroups: comp.sources.bugs Subject: bug fix for SCREEN pgm Message-ID: <49800003@uicsrd> Date: Tue, 24-Nov-87 17:27:00 EST Article-I.D.: uicsrd.49800003 Posted: Tue Nov 24 17:27:00 1987 Date-Received: Sun, 29-Nov-87 18:03:30 EST Lines: 94 Nf-ID: #N:uicsrd:49800003:000:3084 Nf-From: uicsrd.csrd.uiuc.edu!kai Nov 24 16:27:00 1987 I have modified the ReceiveMsg() routine in file screen.c of the virtual terminal manager program "screen" to fix a problem that occured on one of our machines, but could potentially occur on any UNIX machine. The problem occurred when you were already running screen, and you tried to create a new window by executing the command "screen". The message area on the bottom left side of the screen displayed "Short message (2048 bytes)", and the command was never executed. The source of the fix is included in this posting. As the article "A 4.2BSD Interprocess Communication Primer, Draft of July 19, 1984" states; "A Stream socket provides for the bidirectional, reliable, sequenced, and unduplicated flow of data WITHOUT RECORD BOUNDARIES". The original ReceiveMsg() routine expected all 2060 bytes sent from a "client" screen pgm to a "server" screen pgm to make it over in one write/read combination. Because stream sockets can not be relied upon to maintain record boundaries, this is not always the case, so I changed it to loop until all 2060 bytes are read (usually one or two tries). I wrote a test client/server model to prove that UNIX domain stream sockets work without record boundaries. The server loops waiting for connections, then reading from the socket until EOF, reporting the size of each block read. The client reads from standard input (up to a maximum of 8K blocks) and writes exactly what it reads out to the socket, reporting the size of each block read (and subsequently written). The results were interesting. I ran the server on one window in screen, and the client in another, so I could interactively compare the two program results of block sizes. I tried "./client < file", where file was a 25K text file, and client read and wrote three 8K blocks, and one fragment trailing block. Server, however, read a mixture of 2K and 4K blocks. Running the same test on a different brand system produced the same behaviour, but different size blocks read. The code is available upon request. Patrick Wolfe pwolfe@kai.com ..!{uunet,ihnp4}!uiucuxc!kailand!pwolfe Here is the fixed routine ReceiveMsg in file screen.c in it's entirety: static ReceiveMsg (s) { register ns; struct sockaddr_un a; int len = sizeof (a), left; struct msg m; char *n; if ((ns = accept (s, (struct sockaddr *)&a, &len)) == -1) { Msg (errno, "accept"); return; } /* * read variable size stream socket * messages until the structure m is full */ n = (char *) &m; left = sizeof (m); while ((left > 0) && ((len = read (ns, n, left)) > 0)) { left -= len; n += len; } close (ns); if (len == -1) { Msg (errno, "read"); return; } else if (left > 0) { Msg (0, "Short message (%d bytes)", len); return; } switch (m.type) { case MSG_CREATE: ExecCreate (&m); break; case MSG_ERROR: Msg (0, "%s", m.m.message); break; default: Msg (0, "Invalid message (type %d).", m.type); } } Patrick Wolfe pwolfe@kai.com ..!{uunet,ihnp4}!uiucuxc!kailand!pwolfe