summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/tty.c')
-rw-r--r--sys/kern/tty.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index fced5d7..5520b82 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -236,6 +236,7 @@ ttyopen(struct cdev *device, struct tty *tp)
s = spltty();
tp->t_dev = device;
+ tp->t_hotchar = 0;
if (!ISSET(tp->t_state, TS_ISOPEN)) {
ttyref(tp);
SET(tp->t_state, TS_ISOPEN);
@@ -276,6 +277,7 @@ ttyclose(struct tty *tp)
tp->t_gen++;
tp->t_line = TTYDISC;
+ tp->t_hotchar = 0;
tp->t_pgrp = NULL;
tp->t_session = NULL;
tp->t_state = 0;
@@ -1072,18 +1074,25 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
if ((u_int)t >= nlinesw)
return (ENXIO);
- if (t != tp->t_line) {
- s = spltty();
- ttyld_close(tp, flag);
- error = (*linesw[t]->l_open)(device, tp);
- if (error) {
- (void)ttyld_open(tp, device);
- splx(s);
- return (error);
- }
- tp->t_line = t;
- splx(s);
+ if (t == tp->t_line)
+ return (0);
+ s = spltty();
+ ttyld_close(tp, flag);
+ tp->t_line = t;
+ error = ttyld_open(tp, device);
+ if (error) {
+ /*
+ * If we fail to switch line discipline we cannot
+ * fall back to the previous, because we can not
+ * trust that ldisc to open successfully either.
+ * Fall back to the default ldisc which we know
+ * will allways succeed.
+ */
+ tp->t_line = TTYDISC;
+ (void)ttyld_open(tp, device);
}
+ splx(s);
+ return (error);
break;
}
case TIOCSTART: /* start output, like ^Q */
@@ -2905,7 +2914,7 @@ ttyldoptim(struct tty *tp)
tp->t_state |= TS_CAN_BYPASS_L_RINT;
else
tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
- return (linesw[tp->t_line]->l_hotchar);
+ return (tp->t_hotchar);
}
OpenPOWER on IntegriCloud