[net.bugs.usg] bug in tty driver?

ronald@hcrvx1.UUCP (Ron Williams) (09/28/85)

Description:

The following combination of events seems to cause reads of a tty to return
EOF (VAX System V, Rel 2.0, Version 2; but may apply to your system as well):

1) type a character, then backspace
2) have your terminal set into raw mode, then back to canonical mode

This problem arises (for example), if I type vnews<CR>, then n^H, and vnews
decides I have no news.

Prove it:

Place the following text in a file called "foo".
	sleep 10
	: remember previous settings
	x=`stty -g`
	stty raw
	stty $x

Now type:
sh foo<CR>
x^H<no CR>
After 10 seconds, your shell will exit.  This applies to both the tty driver
and the sxt driver.
					Ron Williams
					utzoo!hcrvax!hcrvx1!ronald

mikel@codas.UUCP (Mikel Manitius) (10/04/85)

> Description:
> 
> The following combination of events seems to cause reads of a tty to return
> EOF (VAX System V, Rel 2.0, Version 2; but may apply to your system as well):
> 
> 1) type a character, then backspace
> 2) have your terminal set into raw mode, then back to canonical mode
> 
> This problem arises (for example), if I type vnews<CR>, then n^H, and vnews
> decides I have no news.
> 
> Prove it:
> 
> Place the following text in a file called "foo".
> 	sleep 10
> 	: remember previous settings
> 	x=`stty -g`
> 	stty raw
> 	stty $x
> 
> Now type:
> sh foo<CR>
> x^H<no CR>
> After 10 seconds, your shell will exit.  This applies to both the tty driver
> and the sxt driver.
> 					Ron Williams
> 					utzoo!hcrvax!hcrvx1!ronald

I have tried this on my 3B2 5.2 2.0, it does not throw generate an EOF
for me, however it does create other problems: After running foo, when I
type a character, it is not echoed, the next time I type it, I get a bell,
and the procedure repeats itself, when I try to type different characters,
I get just bells, only when I generate some activity on the keyboard
(ie: typing many characters per second) do they begin to echo. This is
quite interresting.
-- 
                                        =======
     Mikel Manitius                   ==----=====    AT&T
     ...!{ihnp4!}codas!mikel         ==------=====   Information Systems 
     (305) 869-2462                  ===----======   SDSS Regional Support
     AT&T-IS ETN: 755                 ===========    Altamonte Springs, FL
     My opinions are my own.            =======

rossc@metro.oz (Ross Cartlidge) (12/16/85)

In article <130@codas.UUCP> mikel@codas.UUCP (Mikel Manitius) writes:
>> Description:
>> 
>> The following combination of events seems to cause reads of a tty to return
>> EOF (VAX System V, Rel 2.0, Version 2; but may apply to your system as well):
>> 
>> Place the following text in a file called "foo".
>> 	sleep 10
>> 	: remember previous settings
>> 	x=`stty -g`
>> 	stty raw
>> 	stty $x
>> 
>> Now type:
>> sh foo<CR>
>> x^H<no CR>
>> After 10 seconds, your shell will exit.  This applies to both the tty driver
>> and the sxt driver.
>> 					Ron Williams
>> 					utzoo!hcrvax!hcrvx1!ronald

[This explanation assumes good knowledge of System V tty driver]

This behaviour is caused by a failure in a heuristic employed
by the LDCHG ioctl call in tt0 when the ICANON flag is toggled. 
When ICANON is toggled all characters are put back
on the raw queue for reprocessing. The delimiter count(t_delct),
however, is set to the number of characters on the raw queue
as there could be a delimiter in the (unprocessed) raw queue.
Thus in the foo example, above, we have two characters on the
raw queue (x^H) when ICANON toggles off then on. Which
results in x^H remaining on the raw queue (canonical processing is
not done until a read(2) is called) but now the t_delct value
is 2. Which means that read(2) will return after canonical
processing.
Thus when the shell executes a read(2) after executing foo
it will return 0 characters as x^H results in no characters
placed on canon queue. Sh(1) interprets this as on EOF.

FIX:
	The problem of what to do with characters that have been input,
but not read when mode changes occur, cannot be handled elegantly
in SysV as t_delct cannot be set accurately after
a mode change. The best solution is for "canon" in
tty.c to check if t_delct speaks the truth and, if
it can find no delimiters, then it should wait
for more characters before decrementing t_delct and returning
to ttread. The diff(1) listing for io/tty.c
implements this strategy. (I have not indented the for loop
so as to keep the diff listing small)

371a372
> 	int	 gotdelim	= 0;
372a374,375
> 	for (;;)
> {
412a416
> 				gotdelim = 1;
431c435,436
< 		if (c == '\n' || c == tp->t_cc[VEOL] || c == tp->t_cc[VEOL2])
---
> 		if (c == '\n' || c == tp->t_cc[VEOL] || c == tp->t_cc[VEOL2]) {
> 			gotdelim = 1;
432a438
> 		}
435a442,446
> 	if (gotdelim)
> 		break;
> 	else
> 		tp->t_delct = 0;
> }