From 79ccb9aff376fa2289b0b077dcf83549828f84af Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Sun, 30 Jul 1995 13:52:56 +0000 Subject: [PATCH] Don't swap the queue headers to implement concatenation of the queues for TIOCSETA[W]. Swapping an even number of times broke the queue resource limits. This would have broken CRTSCTS flow control if the clist slush list was used up. Don'concatenate the queues for TIOCSETA[W] if one of the queues has a resource limit of 0. Concatenation would cause a panic if one of the queues is nonempty and the other is limited to length 0. This may have caused panics in PPPDISC. Wake up readers after all transitions of ICANON. When ICANON is turned off it is quite likely that characters will become available to be read. Reduce indentation near these changes. --- sys/kern/tty.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 0df97865639..66947ae85ad 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)tty.c 8.8 (Berkeley) 1/21/94 - * $Id: tty.c,v 1.58 1995/07/29 13:35:33 bde Exp $ + * $Id: tty.c,v 1.59 1995/07/30 12:39:16 bde Exp $ */ /*- @@ -840,21 +840,30 @@ ttioctl(tp, cmd, data, flag) } ttsetwater(tp); } - if (cmd != TIOCSETAF) { - if (ISSET(t->c_lflag, ICANON) != - ISSET(tp->t_lflag, ICANON)) - if (ISSET(t->c_lflag, ICANON)) { - SET(tp->t_lflag, PENDIN); - ttwakeup(tp); - } else { - struct clist tq; - + if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) && + cmd != TIOCSETAF) { + if (ISSET(t->c_lflag, ICANON)) + SET(tp->t_lflag, PENDIN); + else { + /* + * XXX we really shouldn't allow toggling + * ICANON while we're in a non-termios line + * discipline. Now we have to worry about + * panicing for a null queue. + */ + if (tp->t_canq.c_cbreserved > 0 && + tp->t_rawq.c_cbreserved > 0) { catq(&tp->t_rawq, &tp->t_canq); - tq = tp->t_rawq; - tp->t_rawq = tp->t_canq; - tp->t_canq = tq; - CLR(tp->t_lflag, PENDIN); + /* + * XXX the queue limits may be + * different, so the old queue + * swapping method no longer works. + */ + catq(&tp->t_canq, &tp->t_rawq); } + CLR(tp->t_lflag, PENDIN); + } + ttwakeup(tp); } tp->t_iflag = t->c_iflag; tp->t_oflag = t->c_oflag;