Fix an awful bug inside our COMPAT_43TTY code.
When I migrated tty_compat.c to MPSAFE TTY, I just hooked it up to the build and fixed it until it compiled and somewhat worked. It turns out this was not the smartest thing, because the old TTY layer also had a field called t_flags, which contained a set of sgtty flags. This means our current COMPAT_43TTY code overwrites the TTY flags, causing all strange problems to occur. Fix this code to use a new struct member called t_compatflags. This commit may cause kern/127054 to be fixed, but this still has to be tested/confirmed by the originator. It has to be fixed anyway. PR: kern/127054
This commit is contained in:
parent
ae590ad889
commit
28aa9d1022
@ -121,7 +121,8 @@ ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term)
|
|||||||
term->c_ospeed = tp->t_termios.c_ospeed;
|
term->c_ospeed = tp->t_termios.c_ospeed;
|
||||||
term->c_cc[VERASE] = sg->sg_erase;
|
term->c_cc[VERASE] = sg->sg_erase;
|
||||||
term->c_cc[VKILL] = sg->sg_kill;
|
term->c_cc[VKILL] = sg->sg_kill;
|
||||||
tp->t_flags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff);
|
tp->t_compatflags = (tp->t_compatflags&0xffff0000) |
|
||||||
|
(sg->sg_flags&0xffff);
|
||||||
ttcompatsetflags(tp, term);
|
ttcompatsetflags(tp, term);
|
||||||
*com = (*com == TIOCSETP) ? TIOCSETAF : TIOCSETA;
|
*com = (*com == TIOCSETP) ? TIOCSETAF : TIOCSETA;
|
||||||
break;
|
break;
|
||||||
@ -160,14 +161,15 @@ ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term)
|
|||||||
case TIOCLBIC:
|
case TIOCLBIC:
|
||||||
case TIOCLSET:
|
case TIOCLSET:
|
||||||
if (*com == TIOCLSET)
|
if (*com == TIOCLSET)
|
||||||
tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
|
tp->t_compatflags = (tp->t_compatflags&0xffff) |
|
||||||
|
*(int *)data<<16;
|
||||||
else {
|
else {
|
||||||
tp->t_flags =
|
tp->t_compatflags = (ttcompatgetflags(tp)&0xffff0000) |
|
||||||
(ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
|
(tp->t_compatflags&0xffff);
|
||||||
if (*com == TIOCLBIS)
|
if (*com == TIOCLBIS)
|
||||||
tp->t_flags |= *(int *)data<<16;
|
tp->t_compatflags |= *(int *)data<<16;
|
||||||
else
|
else
|
||||||
tp->t_flags &= ~(*(int *)data<<16);
|
tp->t_compatflags &= ~(*(int *)data<<16);
|
||||||
}
|
}
|
||||||
ttcompatsetlflags(tp, term);
|
ttcompatsetlflags(tp, term);
|
||||||
*com = TIOCSETA;
|
*com = TIOCSETA;
|
||||||
@ -209,7 +211,7 @@ tty_ioctl_compat(struct tty *tp, u_long com, caddr_t data, struct thread *td)
|
|||||||
compatspeeds);
|
compatspeeds);
|
||||||
sg->sg_erase = cc[VERASE];
|
sg->sg_erase = cc[VERASE];
|
||||||
sg->sg_kill = cc[VKILL];
|
sg->sg_kill = cc[VKILL];
|
||||||
sg->sg_flags = tp->t_flags = ttcompatgetflags(tp);
|
sg->sg_flags = tp->t_compatflags = ttcompatgetflags(tp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TIOCGETC: {
|
case TIOCGETC: {
|
||||||
@ -237,10 +239,10 @@ tty_ioctl_compat(struct tty *tp, u_long com, caddr_t data, struct thread *td)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TIOCLGET:
|
case TIOCLGET:
|
||||||
tp->t_flags =
|
tp->t_compatflags =
|
||||||
(ttcompatgetflags(tp) & 0xffff0000UL)
|
(ttcompatgetflags(tp) & 0xffff0000UL)
|
||||||
| (tp->t_flags & 0xffff);
|
| (tp->t_compatflags & 0xffff);
|
||||||
*(int *)data = tp->t_flags>>16;
|
*(int *)data = tp->t_compatflags>>16;
|
||||||
if (ttydebug)
|
if (ttydebug)
|
||||||
printf("CLGET: returning %x\n", *(int *)data);
|
printf("CLGET: returning %x\n", *(int *)data);
|
||||||
break;
|
break;
|
||||||
@ -329,7 +331,7 @@ ttcompatgetflags(struct tty *tp)
|
|||||||
static void
|
static void
|
||||||
ttcompatsetflags(struct tty *tp, struct termios *t)
|
ttcompatsetflags(struct tty *tp, struct termios *t)
|
||||||
{
|
{
|
||||||
int flags = tp->t_flags;
|
int flags = tp->t_compatflags;
|
||||||
tcflag_t iflag = t->c_iflag;
|
tcflag_t iflag = t->c_iflag;
|
||||||
tcflag_t oflag = t->c_oflag;
|
tcflag_t oflag = t->c_oflag;
|
||||||
tcflag_t lflag = t->c_lflag;
|
tcflag_t lflag = t->c_lflag;
|
||||||
@ -406,7 +408,7 @@ ttcompatsetflags(struct tty *tp, struct termios *t)
|
|||||||
static void
|
static void
|
||||||
ttcompatsetlflags(struct tty *tp, struct termios *t)
|
ttcompatsetlflags(struct tty *tp, struct termios *t)
|
||||||
{
|
{
|
||||||
int flags = tp->t_flags;
|
int flags = tp->t_compatflags;
|
||||||
tcflag_t iflag = t->c_iflag;
|
tcflag_t iflag = t->c_iflag;
|
||||||
tcflag_t oflag = t->c_oflag;
|
tcflag_t oflag = t->c_oflag;
|
||||||
tcflag_t lflag = t->c_lflag;
|
tcflag_t lflag = t->c_lflag;
|
||||||
|
@ -103,6 +103,7 @@ struct tty {
|
|||||||
struct winsize t_winsize; /* (t) Window size. */
|
struct winsize t_winsize; /* (t) Window size. */
|
||||||
unsigned int t_column; /* (t) Current cursor position. */
|
unsigned int t_column; /* (t) Current cursor position. */
|
||||||
unsigned int t_writepos; /* (t) Where input was interrupted. */
|
unsigned int t_writepos; /* (t) Where input was interrupted. */
|
||||||
|
int t_compatflags; /* (t) COMPAT_43TTY flags. */
|
||||||
|
|
||||||
/* Init/lock-state devices. */
|
/* Init/lock-state devices. */
|
||||||
struct termios t_termios_init_in; /* tty%s.init. */
|
struct termios t_termios_init_in; /* tty%s.init. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user