Path: utzoo!attcan!uunet!auspex!guy From: guy@auspex.auspex.com (Guy Harris) Newsgroups: comp.unix.questions Subject: Re: BSD vs. SVR4 typehead flush after tty mode change Message-ID: <4187@auspex.auspex.com> Date: 13 Oct 90 21:34:37 GMT References: <10704@uudell.dell.com> <14028@smoke.BRL.MIL> <15042@cbmvax.commodore.com> Organization: Auspex Systems, Santa Clara Lines: 63 >The fix: OK, now *after* you've applied the fix, try the following: Fire up the (S5R4) C shell. Turn on filename completion ("set filec"). Do: stty -icanon min 1 time 0; sleep 10; stty icanon eof eol and type "cat /etc/m" after hitting after the preceding command line If you get bizarre behavior from the C shell - for example, a listing of all files in "/etc" whose names begin with "m", or worse - you have just discovered why I put that flush into the SunOS 4.0 "tty_ldterm.c" (which is why it's in the S5R4 "ldterm.c", it being derived from the SunOS "tty_ldterm.c"). If you don't, I suspect "ldterm" has been changed to 1) request M_READ notification and 2) *NOT* to send anything upstream until it's asked for by an M_READ. If so, this raises the question of how "poll()" can figure out there's stuff to be read if it's not at the stream head.... The problem is that, in non-canonical mode, input is sent upstream in streams messages in such a fashion that the boundaries between messages aren't relevant, so that stuff gets upstream without waiting for an NL. The stream head is running in "byte stream" mode, so the stream head doesn't care about the boundaries between messages in any case. In *canonical* mode, there is one line per stream head (where a "line" is terminated by an NL, or by the EOF character, or by either of the two "alternate end-of-line" characters), and the stream head is in message-nondiscard mode. This is necessary in order to implement standard UNIX cooked-mode tty semantics, i.e. in order to have a "read()" return at most one line. Unfortunately, if, say, the tty were in non-canonical mode (with, say, MIN 1 and TIME 0), and you typed "cat /etc/m", this would probably get sent upstream as several streams messages, one with "c", one with "a", one with "t", etc.. When the tty is switched to canonical mode, and thus the stream head is switched to message-nondiscard mode, some process doing a "read()" will then have the "read()" succeed, returning one character - the "c". This looks to that program as if the user had typed "a" followed by the EOF character. The C shell, with filename completion set, will, at the appropriate time, respond appropriately to this - i.e., it'll give a listing of the possible completions of the string. Now, as indicated, one possible fix would be to have "ldterm" never send anything upstream until it knows (or, at least, has a good guess about) whether what it's sending upstream is to be read in canonical or non-canonical mode. Unfortunately, as indicated, this makes life more difficult for "poll()", as it can no longer simply check out the stream head to see whether a "read()" on a file descriptor will block or not; it has to send a notification downstream to ask whether anybody below the stream head is withholding any data pending an M_READ message.