[net.bugs.4bsd] 4.2BSD Script drops characters

crp@ccivax.UUCP (Chuck Privitera) (11/09/84)

Index:	ucb/script.c 4.2BSD/(2.9BSD?)

Description:
	When running script on a terminal with a small input
	buffer, (like a vt100), the terminal drops characters.
	However, the "capture" file has all of the data in it.
Repeat-By:
	I noticed it by simply doing a diff -c5. Try cat'ing a
	long file, or holding down the no-scroll button for a while.
	The vt100 displays "error" characters interspersed with
	the output, and the output is obviously not complete.
	(i.e. words may be joined together, etc.). We have installed
	the pty speedup posted by uthub!thomson, which I suspect
	caused this problem (by feeding data to the control terminal
	faster). Thus, you may not see this problem very frequently.
	(You should see it by the second method above nevertheless).
Fix:
	Anyways, the fix is to put the control terminal into CBREAK
	mode instead of RAW mode, so that when the terminal (or the
	user) sends an XOFF (DC3/023) character, the host can stop
	sending data until it receives an XON (DC1/021). Since the
	vt100 sends XOFF/XON like crazy, (and displays the error
	character on buffer overflow) those of you with vt100s will
	see this behaviour more often. Not that it's needed but,
	here is a context diff of the change:


rcsdiff -c5 script.c
RCS file: RCS/script.c,v
retrieving revision 1.1
diff -c5 -r1.1 script.c
*** /tmp/,RCSt1006462   Fri Nov  9 14:31:11 1984
--- script.c    Wed Oct 31 15:38:57 1984
***************
*** 154,164
  fixtty()
  {
        struct sgttyb sbuf;
  
        sbuf = b;
!       sbuf.sg_flags |= RAW;
        sbuf.sg_flags &= ~ECHO;
        ioctl(0, TIOCSETP, (char *)&sbuf);
  }
  
  fail()

--- 154,164 -----
  fixtty()
  {
        struct sgttyb sbuf;
  
        sbuf = b;
!       sbuf.sg_flags |= CBREAK;
        sbuf.sg_flags &= ~ECHO;
        ioctl(0, TIOCSETP, (char *)&sbuf);
  }
  
  fail()

anton@ucbvax.ARPA (Jeff Anton) (11/12/84)

In article <219@ccivax.UUCP> crp@ccivax.UUCP (Chuck Privitera) writes:
>Index:	ucb/script.c 4.2BSD/(2.9BSD?)
>
>Description:
>	When running script on a terminal with a small input
>	buffer, (like a vt100), the terminal drops characters.
>	However, the "capture" file has all of the data in it.
>Repeat-By:
>	I noticed it by simply doing a diff -c5. Try cat'ing a
>	long file, or holding down the no-scroll button for a while.
>	The vt100 displays "error" characters interspersed with
>	the output, and the output is obviously not complete.
>	(i.e. words may be joined together, etc.). We have installed
>	the pty speedup posted by uthub!thomson, which I suspect
>	caused this problem (by feeding data to the control terminal
>	faster). Thus, you may not see this problem very frequently.
>	(You should see it by the second method above nevertheless).
>Fix:
>	Anyways, the fix is to put the control terminal into CBREAK
>	mode instead of RAW mode, so that when the terminal (or the
>	user) sends an XOFF (DC3/023) character, the host can stop
>	sending data until it receives an XON (DC1/021). Since the
>	vt100 sends XOFF/XON like crazy, (and displays the error
>	character on buffer overflow) those of you with vt100s will
>	see this behaviour more often. Not that it's needed but,
>	here is a context diff of the change:
>
>
>rcsdiff -c5 script.c

>RCS file: RCS/script.c,v
>retrieving revision 1.1
>diff -c5 -r1.1 script.c
>*** /tmp/,RCSt1006462   Fri Nov  9 14:31:11 1984
>--- script.c    Wed Oct 31 15:38:57 1984
>***************
>*** 154,164
>  fixtty()
>  {
>        struct sgttyb sbuf;
>  
>        sbuf = b;
>!       sbuf.sg_flags |= RAW;
>        sbuf.sg_flags &= ~ECHO;
>        ioctl(0, TIOCSETP, (char *)&sbuf);
>  }
>  
>  fail()
>
>--- 154,164 -----
>  fixtty()
>  {
>        struct sgttyb sbuf;
>  
>        sbuf = b;
>!       sbuf.sg_flags |= CBREAK;
>        sbuf.sg_flags &= ~ECHO;
>        ioctl(0, TIOCSETP, (char *)&sbuf);
>  }
>  
>  fail()

The above fix does only half the job.  In cbreak mode interupt chars from
the terminal will be caught and delivered to the script program which is
not set up to handle them properly.  Rlogin solves this problem by setting
cbreak mode and turning off all the special charactors other then
^s/^q (whatever those are called escapes me for the moment).
Another problem related to peudo-terminals and rlogin like programs
is that if you set a delay on a peudo-terminal (like ff1, nl2 etc..)
the delay is encoded as a byte with the parity bit set and the rest
of the byte is a delay in hz count.  On the vaxs around here this
causes a tab to be output after a nl when nl2 is set in a script or
rlogin (because the delay count = 9 and 9 is the tab char) ex.

% script
script started .....
% stty nl2
%
<--tab->% exit
script done ....
%
				Jeff Anton
				...!ucbvax!anton
				anton@berkeley.ARPA

(I don't often write the stuff; I just use it)

crp@ccivax.UUCP (Chuck Privitera) (11/14/84)

Description:
	In article <3197@ucbvax.ARPA> Jeff Anton points out:
> ....
> In cbreak mode interupt chars from the terminal will be
> caught and delivered to the script program which is
> not set up to handle them properly.
	An oversight on my part, sorry for the inconvenience.
	I just noticed this yesterday when I used script
	to post some bug reports.
Repeat-by:
	Apply the cbreak fix article <219@ccivax.UUCP> then
	run script. When the interupt or quit character is typed
	script will exit leaving the terminal in cbreak mode
	and -echo. (typing the suspend character will suspend
	script, probably NOT what you wanted)
Fix:
	Turn off all special characters except start/stop.

rcsdiff -c3 -r1.2 script.c
RCS file: RCS/script.c,v
retrieving revision 1.2
diff -c3 -r1.2 script.c
*** /tmp/,RCSt1002637	Wed Nov 14 09:10:11 1984
--- script.c	Wed Nov 14 09:09:05 1984
***************
*** 151,156
  	fail();
  }
  
  fixtty()
  {
  	struct sgttyb sbuf;

--- 151,159 -----
  	fail();
  }
  
+ struct tchars ntc = { -1, -1, -1, -1, -1, -1 };
+ struct ltchars nlc = { -1, -1, -1, -1, -1, -1 };
+ 
  fixtty()
  {
  	struct sgttyb sbuf;
***************
*** 159,164
  	sbuf.sg_flags |= CBREAK;
  	sbuf.sg_flags &= ~ECHO;
  	ioctl(0, TIOCSETP, (char *)&sbuf);
  }
  
  fail()

--- 162,171 -----
  	sbuf.sg_flags |= CBREAK;
  	sbuf.sg_flags &= ~ECHO;
  	ioctl(0, TIOCSETP, (char *)&sbuf);
+ 	ntc.t_startc = tc.t_startc;
+ 	ntc.t_stopc = tc.t_stopc;
+ 	ioctl(0, TIOCSETC, (char *)&ntc);
+ 	ioctl(0, TIOCSLTC, (char *)&nlc);
  }
  
  fail()
***************
*** 172,177
  {
  
  	ioctl(0, TIOCSETP, (char *)&b);
  	printf("Script done, file is %s\n", fname);
  	exit(0);
  }

--- 179,186 -----
  {
  
  	ioctl(0, TIOCSETP, (char *)&b);
+ 	ioctl(0, TIOCSETC, (char *)&tc);
+ 	ioctl(0, TIOCSLTC, (char *)&lc);
  	printf("Script done, file is %s\n", fname);
  	exit(0);
  }