[comp.sys.sun] losing input when switching from CBREAK to COOKED in SunOS-4

jw@sics.se (Johan Widen) (02/10/90)

I have a problem with typeahead in my interactions with tcsh on SunOS-4.
The input buffer seems to be flushed when the shell switches from CBREAK
to COOKED. I remember that this was the case in older versions of UNIX
(like v7) and I seem to remember someone mentioning that this "feature"
was put back into SunOS-4 for some reason.

Is this just a problem with my shell and is there a work around?

Here is an example of what I mean:

On a Sun:

> sleep 30
/bin/echo hi
/bin/echo ho
ed Makefile
2
1,5p
> /bin/echo hi
hi

Nothing more happens. (I inserted the ed command just to point out to the
bash freaks out there that the current version of bash does not handle
this very gracefully either).

Now here is what happens on a Sequent Symmetry under DYNIX, and also on a
NeXT (I have to hit return when ed has printed "5819"):

> sleep 30
/bin/echo hi
/bin/echo ho
ed Makefile
2
1,5p
> /bin/echo hi
hi
> /bin/echo ho
ho
> ed Makefile
5819

#       Makefile        4.3     6/11/83
#
#       Makefile        4.3     6/11/83
#
# C Shell with process control; VM/UNIX VAX Makefile
# Bill Joy UC Berkeley; Jim Kulp IIASA, Austria
#

Nothing more happens.

Johan Widen
SICS, PO Box 1263, S-164 28 KISTA, SWEDEN	Internet: jw@sics.se
Tel: +46 8 752 15 32	Ttx: 812 61 54 SICS S	Fax: +46 8 751 72 30

ted@arsocomvax.socom.mil (Ted Nolan) (02/14/90)

>I have a problem with typeahead in my interactions with tcsh on SunOS-4.
>The input buffer seems to be flushed when the shell switches from CBREAK
>to COOKED. I remember that this was the case in older versions of UNIX

I have seen the same problem, and since it breaks certain applications of
braggtools (plug..), I sent in a bug report to hotline.  Slightly edited,
it and a couple of responses appear below:

***** 8< Cut Here >8 ******

X-To: hotline@sun.com
X-Subject: TIOCSETN (TCSETS) broken in 4.0.3?

I have recently noticed a problem in SunOS4.0.3 (my hardware is Sun3).
The following program demonstrates the bug:


#include <stdio.h>
#include <sgtty.h>

main()
{
	struct sgttyb tparms_ori;
	struct sgttyb tparms_new;

	char c;

	if(ioctl(0,TIOCGETP,&tparms_ori) < 0){
		perror("Get parms ioctl");
		exit(1);
	}

	tparms_new = tparms_ori;

	tparms_new.sg_flags |= CBREAK;

	if(ioctl(0,TIOCSETP,&tparms_new) < 0){
		perror("Set parms ioctl");
		exit(1);
	}

	if(read(0, &c,1) < 0){
		perror("read");
		exit(1);
	}


	if(ioctl(0,TIOCSETN,&tparms_ori) < 0){
		perror("Reset parms ioctl");
		exit(1);
	}
}


If you run this program on a 4.0.3 system, in a shelltool or commandtool
window, the TIOCSETN discards waiting input, even though its function is
specifically NOT to do that.  Here's an example:

1) type the ls command in a LOCAL shelltool or commandtool window.
2) Using the mouse, grab the ls command, including the carraige return.
3) Run the program above
4) Stuff or paste the ls command into the window.

Since the program only demands one character input, and then does a
TIOCNSEN, the proper response would be 

			s: Command not found.

When the bug is present, you will simply get your prompt back.  This
program works correctly on 3.5 machines, and on 4.0.3 machines through an
rlogin.

A fix or workaround would be greatly appreciated.

				Thanks,
				Ted Nolan
				ted@arsocomvax.socom.mil


X-From: chico@EBay.Sun.COM (Chico Marx)
X-Subject: Re: TIOCSETN (TCSETS) broken in 4.0.3?

Thank you for using Software Support Hotline, your call has been
dispatched to an engineer and you should be receiving a response shortly.
Please reference so#406737 when calling in.  If I can help in any way,
please contact me at the number below.

Thank you

Melissa Taylor
(408)276-3758

X-To:      hotline@sun.com
X-Subject: Re: TIOCSETN (TCSETS) broken in 4.0.3? 

Any progress on so#406737?

X-From: melissat@EBay.Sun.COM (Melissa Taylor)
X-Subject: Re: TIOCSETN (TCSETS) broken in 4.0.3?

I received your e-mail requesting status on so# 406737 and have forwarded
your mail to Chris Johnson the engineer who is assigned to your call. If
you have any questions please call me at the below number.

Thanks,

Melissa Taylor
(408) 276-3758


So.. they know about it, it's so#406737, and supposedly someone is working on
it.  If I don't hear anything in a few weeks maybe I'll give them a call.


				Ted Nolan
				ted@arsocomvax.socom.mil

jw@sics.se (Johan Widen) (02/15/90)

>>>>> In article <4904@brazos.Rice.edu>, jw@sics.se (Johan Widen) writes:
| X-Sun-Spots-Digest: Volume 9, Issue 41, message 4
| I have a problem with typeahead in my interactions with tcsh on SunOS-4.
| The input buffer seems to be flushed when the shell switches from CBREAK
| to COOKED. I remember that this was the case in older versions of UNIX
| (like v7) and I seem to remember someone mentioning that this "feature"
| was put back into SunOS-4 for some reason.

I got the following response from guy@auspex.com (Guy Harris)

| It was.  The problem is that with a streams-based tty driver, when in
| cooked mode each line must be a single streams message and the stream
| head must be in "message-nondiscard" mode, so that a "read" gets no more
| than one line (which is the standard UNIX behavior and is, I think,
| documented).  In uncooked mode, you send stuff up as soon as it arrives,
| basically, and run in "byte-stream" mode, so that the input looks like a
| stream of characters with no delimiters.
|
| Unfortunately, this means that mode generated when in "uncooked" mode
| looks, if read when in "cooked" mode, like a bunch of tiny lines with ^D
| typed at the end of them, which confuses the living hell out of many
| programs reading the input - including the C shell with file name
| completion.
|
| The flushing is unfortunate, and wouldn't have been put it had it not
| been necessary, but the alternative was worse (file name completion was
| basically unusable).  If somebody has a good way of getting the data
| queued up at the stream head reprocessed by the "line discipline"
| streams module without doing violence the the entire streams mechanism,
| Sun (and AT&T, since the SunOS 4.x tty driver is the basis of the S5R4
| tty driver) would probably love to hear about it.... 

This seems to be a tough problem. I implemented a partial workaround for
tcsh. The idea is stolen from bash: just before switching into CBREAK do a
FIONREAD ioctl to check if there is an input record that can be read in
cooked mode. If so, then we stay in cooked mode, read the line, execute
the command and start over again. We thus try to avoid going into CBREAK
mode.

This works well for the case of traditional type ahead: the user types new
commands/whatever while a command is running.

However, it is still not possible to paste several lines at the shell
prompt. All lines except the first will be lost, as the shell is initially
in CBREAK mode.

Johan Widen
SICS, PO Box 1263, S-164 28 KISTA, SWEDEN	Internet: jw@sics.se
Tel: +46 8 752 15 32	Ttx: 812 61 54 SICS S	Fax: +46 8 751 72 30

gray@unix.cis.pitt.edu (Gray Watson) (02/19/90)

In article <4992@brazos.Rice.edu> jw@sics.se (Johan Widen) writes:
>| I have a problem with typeahead in my interactions with tcsh on SunOS-4.
>| The input buffer seems to be flushed when the shell switches from CBREAK
>| to COOKED.

I noticed that SunOS 4.0 csh does not have this problem.  Does anyone have
source for this that can find out what it is doing to combat the flushed
typeahead?

dupuy@cs.columbia.edu (02/21/90)

 > > I have a problem with typeahead in my interactions with tcsh on SunOS-4.
 > > The input buffer seems to be flushed when the shell switches from CBREAK
 > > to COOKED.

 > I noticed that SunOS 4.0 csh does not have this problem.  Does anyone have
 > source for this that can find out what it is doing to combat the flushed
 > typeahead?

The file completion in the "regular" csh provided in 4.3 BSD and SunOS 4.0
doesn't use CBREAK mode - it is always running in COOKED.  It sets ESC to
be the second end-of-line character so that whenever the user types ESC,
the shell gets the current line.  It then retypes over the existing line,
adding any file completion.  However, this method doesn't allow more than
one special character, and thus can't be used for custom line editing like
tcsh, ksh, and bash provide.