Path: utzoo!censor!becker!geac!jtsv16!uunet!auspex!guy From: guy@auspex.auspex.com (Guy Harris) Newsgroups: comp.unix.questions Subject: Re: termios question, PENDIN option Message-ID: <2640@auspex.auspex.com> Date: 16 Nov 89 23:24:03 GMT References: <2057@ncr-sd.SanDiego.NCR.COM> Reply-To: guy@auspex.auspex.com (Guy Harris) Distribution: usa Organization: Auspex Systems, Santa Clara Lines: 91 >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 , 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 . 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", the shell sees "cat /etc/passw" 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.