[comp.unix.questions] termios question, PENDIN option

kit@booboo.SanDiego.NCR.COM (Kit Chow) (11/14/89)

Does anyone know how the PENDIN c_lflag option is used in SVR.4.0
termio(7)? The description of PENDIN in the manual page is:

	"Retype pending input at next read or input character"

I believe that the C shell file completion code uses this feature.
Any information about PENDIN and how the C shell uses this would be
greatly appreciated.

Kit Chow

guy@auspex.auspex.com (Guy Harris) (11/17/89)

>Does anyone know how the PENDIN c_lflag option is used in SVR.4.0
>termio(7)?
>The description of PENDIN in the manual page is:
>
>	"Retype pending input at next read or input character"
>
>I believe that the C shell file completion code uses this feature.

Yes, it does, unfortunately.  It also does TIOCSTI's with echo turned
off, and various other acts that make life difficult for certain kinds
of "editor-based shell windows" (e.g., the Sunview "cmdtool").

>Any information about PENDIN and how the C shell uses this would be
>greatly appreciated.

Well, from the SunOS 4.0 TERMIO(4):

     If PENDIN is set, any input that has not yet been read  will
     be reprinted when the next character arrives as input.

Basically, it causes any input that's been collected but not handed
upstream to be removed from the input queue and then re-run through the
input processing mechanism.  (The same is true in 4.xBSD.)  I.e., if
you've typed "foobar" but no <RETURN>, and are in canonical mode, the
line being assembled - that is, the "foobar" - will be undone, and then
the "foobar" will be treated as input again, so you'll see another
"foobar" echoed if ECHO is on.  However, only the "foobar" will be in
the input queue.

And, as for the way the C shell uses it:

Whoever decided to use these particular techniques (Ken Greer, probably,
as his name appears on the C shell code that uses them) perhaps decided
that it was too costly to just have the C shell run in uncooked, no-echo
mode, and do all the input processing itself.  They may be right,
although I was quite happy with the Korn shell doing so; the machines in
question weren't overloaded time-sharing machines, though, so maybe if
you've got 50 users on an 11/750 or something similarly unfortunate, it
actually makes a difference. 

The mechanism they chose to avoid running in uncooked, no-echo mode was:

	1) Set the "secondary end-of-line" character in the tty driver
	   to be ESC, which is the "complete" character telling the
	   shell to try to do completion on the current string; this
	   means that the "line", in effect, ends when the user hits
	   <ESC>.  The "query" character, used by the user to ask the
	   shell to list all the completions, is ^D; that's normally the
	   EOF character, so it also terminates the "line".

	2) This means that if you type "cat /etc/passw<ESC>", the shell
	   sees "cat /etc/passw<ESC>" as a line, and those characters
	   are no longer part of the "line" being accumulated.  The
	   shell wants to "give them back" to the tty driver, so that
	   the "line" being accumulated again becomes "cat /etc/passw",
	   and then give the "d" back to the tty driver as well.

	3) The TIOCSTI "ioctl" permits it to "give characters back" to
	   the tty driver.  However, if echo is on, they are echoed,
	   since TIOCSTI causes the driver to pretend that the character
	   in question had just been typed.  However, the "cat
	   /etc/passw" is on the screen, so it doesn't want to have
	   them echoed.  Thus, it turns echoing off and TIOCSTI's the
	   characters in question.  It then turns echoing back on, and
	   echoes whatever characters compose the completion of the
	   string.

	4) However, as noted in the comment in the completion code:

		/*
		 * Tabs in the input line cause trouble after a pushback.
		 * tty driver won't backspace over them because column
		 * positions are now incorrect. This is solved by retyping
		 * over current line.
		 */

	   I.e., this TIOCSTI'ing may confuse the tty driver.  So, to
	   fix this, it:

		1) it sends a CR to the terminal, to zip the cursor back
		   to column 0;

		2) reprints the prompt;

		3) pushes the characters back, still with echoing off;

		4) sets the PENDING flag, so that those characters will
		   be "retyped", this time with echoing on.

	  The net effect of 2), 3), and 4) is to cause everything that
	  was on the line to be printed all over again.

merlyn@iwarp.intel.com (Randal Schwartz) (11/21/89)

In article <2640@auspex.auspex.com>, guy@auspex (Guy Harris) writes:
| And, as for the way the C shell uses it:
[...]
| 		1) it sends a CR to the terminal, to zip the cursor back
| 		   to column 0;
| 
| 		2) reprints the prompt;
| 
| 		3) pushes the characters back, still with echoing off;
| 
| 		4) sets the PENDING flag, so that those characters will
| 		   be "retyped", this time with echoing on.
| 
| 	  The net effect of 2), 3), and 4) is to cause everything that
| 	  was on the line to be printed all over again.

And, all *this* is supposed to be cheaper than running in raw mode?
Gaaccccckkkkk!

(My hatred of the C-shell and other Bezerkly-isms just got one notch
higher.)

Just another person with fond memories of the "simpler" UNIX systems,
-- 
/== Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ====\
| on contract to Intel's iWarp project, Hillsboro, Oregon, USA, Sol III  |
| merlyn@iwarp.intel.com ...!uunet!iwarp.intel.com!merlyn	         |
\== Cute Quote: "Welcome to Oregon... Home of the California Raisins!" ==/

chris@mimsy.umd.edu (Chris Torek) (11/22/89)

In article <2640@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>... So, to fix this, [tcsh]:
>	1) it sends a CR to the terminal, to zip the cursor back
>	   to column 0;
>	2) reprints the prompt;
>	3) pushes the characters back, still with echoing off;
>	4) sets the PENDING flag, so that those characters will
>	   be "retyped", this time with echoing on.

Of course, instead of all this insanity, it could simply:

	1) send CR; 2) reprint the prompt; 3) push the characters
	back WITH ECHO ENABLED.

This would cut down on the number of system calls.

(Of course, if the machine is heavily loaded or otherwise slow, and
you type something while the characters are being `pushed back',
what you typed will come out in the middle of the pushed-back
characters, no matter what method is used to push them back.  That is,
the sequence of events will be:

		to push back `hello world':
	TIOCSTI('h')		raw queue now `h'
	TIOCSTI('e')		raw queue now `he'
	TIOCSTI('l')		raw queue now `hel'
	input interrupt: `f'	raw queue now `helf'
	TIOCSTI('l')		raw queue now `helfl'
	. . .

This routinely happens to me in ucb mail, which uses TIOCSTI for
header editing.  It is extremely annoying.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris