termios question, PENDIN option

Guy Harris guy at auspex.auspex.com
Fri Nov 17 10:24:03 AEST 1989


>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.



More information about the Comp.unix.questions mailing list