Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/18/84; site bbncc5.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!bbnccv!bbncc5!jr
From: jr@bbncc5.UUCP (John Robinson)
Newsgroups: net.sources
Subject: stdio improvement for 4.2
Message-ID: <898@bbncc5.UUCP>
Date: Tue, 29-Oct-85 09:30:48 EST
Article-I.D.: bbncc5.898
Posted: Tue Oct 29 09:30:48 1985
Date-Received: Wed, 30-Oct-85 07:45:52 EST
Reply-To: jr@bbnccv.UUCP (John Robinson)
Organization: Bolt Beranek and Newman, Cambridge, MA
Lines: 47

In debugging a redisplay problem with GNU emacs, I found that the
write() system call will sometimes (apparently due to caught signals)
return before having written all it was asked.  Seems the auto-resume
feature of 4.2 slow-device output is not completed.

At any rate, this causes stdio problems (turns on the error bit in the
file block), and makes for a bizarre-looking screen.  I modified
flsbuf.c to cause stdio to restart the failed write(), and now all
seems to work fine.

This is the RCS line from the file I used:

/* @(#)flsbuf.c	4.6 (Berkeley) 6/30/83 */

Here are the changes.  The first is to _flsbuf() and the second to
fflush().  The latter is really the one that emacs seems to need:

70,72c70,77
< 	if (rn != n) {
< 		iop->_flag |= _IOERR;
< 		return(EOF);
---
> 	for (;rn != n;) {
> 		/* If write sent nothing or failed, give up */
> 		if (n <= 0) {
> 			iop->_flag |= _IOERR;
> 			return(EOF);
> 		}
> 		base += n; rn -= n;
> 		n = write(fileno(iop), base, rn);
81a87
>   register int wn;
87,89c93,102
< 	if (write(fileno(iop), base, n) != n) {
< 	    iop->_flag |= _IOERR;
< 	    return(EOF);
---
> 	wn = write(fileno(iop), base, n);
> 	/* This retries the write until it decides it's a lost cause */
> 	for (;wn != n;) {
> 	    if (wn <= 0) {
> 		iop->_flag |= _IOERR;
> 		return(EOF);
> 	      }
> 	    base += wn;
> 	    n -= wn;
> 	    wn = write(fileno(iop), base, n);