Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!linus!decvax!harpo!seismo!hao!hplabs!sri-unix!jpayne@bbn-vax
From: jpayne@bbn-vax@sri-unix.UUCP
Newsgroups: net.unix-wizards
Subject: Interrupting programs that are doing output to terminals.
Message-ID: <3421@sri-arpa.UUCP>
Date: Mon, 25-Jul-83 09:10:39 EDT
Article-I.D.: sri-arpa.3421
Posted: Mon Jul 25 09:10:39 1983
Date-Received: Tue, 26-Jul-83 16:23:58 EDT
Lines: 85

From:  Jonathan Payne 

Typing ^C causes the write system call to return and causes the terminal
output queue to be flushed, right?  If the new signal mechanism (SM) is
used, the write will return the number of characters written if any were
written, or restarts without telling the user.  In the case where the
write is aborted, it does no good to know how many characters were
written, because the output queue is flushed.  So in fact a completely
random number of characters actually make it to the terminal. For
programs that NEED to know exactly what has been written, an editor
for example, this is no good.

A solution to this problem is to have another ioctl which says NOT to
flush output on interrupts.  But in the routine ntwrite in ttynew.c,
this solution doesn't quite work (if I understand it correctly).

	while (u.u_count) {
		cc = MIN(u.u_count, OBUFSIZ);
		cp = obuf;
		iomove(cp, (unsigned)cc, B_WRITE);
		...
	}

Iomove copies from u.u_base into cp which is OBUFSIZ long.  Iomove also
decrements u.u_count, so the io is LOGICALLY complete at this time (if
an interrupt is received now).  This iomove is an optimization I guess,
and the second part of this optimization is this:

		while (cc) {
			if (tp->t_flags&RAW || tp->t_local&LLITOUT)
				ce = cc;
			else {
				ce=0;
				while(((partab[*(unsigned char *)(cp+ce)]&077)==0)&&(cet_rocount = 0;
					if (ntyoutput(*cp, tp) >= 0) {
						ttstart(tp);
						sleep((caddr_t)&lbolt, TTOPRI);
						continue;
					}
					cp++;
					cc--;
					if (tp->t_outq.c_cc > hiwat)
						goto ovhiwat;
				}
			}
			tp->t_rocount = 0;
			i=b_to_q(cp,ce,&tp->t_outq);
			ce-=i;
			tk_nout+=ce;
			tp->t_col+=ce;
			cp+=ce;
			cc-=ce;
			if (i) {
				ttstart(tp);
				sleep((caddr_t)&lbolt, TTOPRI);
			}
			if (ce || tp->t_outq.c_cc > hiwat)
				goto ovhiwat;
		}

What this algorithm tries to do is put the characters on the output queue
as fast as possible by using b_to_q for n characters instead of n calls
to ntyoutput like it did in the old v7 system.  But it can't simply put
any character on the output queue e.g. '\n' has to be treated specially
to do the delays ...  That what this is for:
			while(((partab[*(unsigned char *)(cp+ce)]&077)==0)&&(ce