diff options
author | ed <ed@FreeBSD.org> | 2008-08-22 21:27:37 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2008-08-22 21:27:37 +0000 |
commit | a6b774bc3b273e7c391ec85e6c7e92dffc7d1354 (patch) | |
tree | 4db7daeb534af1031c775e094e144ae927c7de23 | |
parent | 2c1bd90c13f2eaa2d33f7132e4df07198e5658c3 (diff) | |
download | FreeBSD-src-a6b774bc3b273e7c391ec85e6c7e92dffc7d1354.zip FreeBSD-src-a6b774bc3b273e7c391ec85e6c7e92dffc7d1354.tar.gz |
Fix two small bugs in tcsetattr().
- According to POSIX, tcsetattr() must not fail when any of the bits in
the structure are unsupported, but it must leave the unsupported flags
alone.
- The CIGNORE flag (set by TCSASOFT, extension) was not cleared from
c_cflag, which means using it would cause it to be applied during its
entire lifespan. Eventually make sure we clear the flag.
I don't really like CIGNORE, but I think we must keep it alive right
now. With our new TTY layer, we don't actually need this mechanism,
because if you leave c_cflag, c_ispeed and c_ospeed alone, we won't make
a call into the device driver anyway.
Reported by: naddy
Tested by: naddy
-rw-r--r-- | sys/kern/tty.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c index aaa43fc..15a48a4 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1332,12 +1332,11 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td) if (t->c_ispeed == 0) t->c_ispeed = t->c_ospeed; - /* Don't allow invalid flags to be set. */ - if ((t->c_iflag & ~TTYSUP_IFLAG) != 0 || - (t->c_oflag & ~TTYSUP_OFLAG) != 0 || - (t->c_lflag & ~TTYSUP_LFLAG) != 0 || - (t->c_cflag & ~TTYSUP_CFLAG) != 0) - return (EINVAL); + /* Discard any unsupported bits. */ + t->c_iflag &= TTYSUP_IFLAG; + t->c_oflag &= TTYSUP_OFLAG; + t->c_lflag &= TTYSUP_LFLAG; + t->c_cflag &= TTYSUP_CFLAG; /* Set terminal flags through tcsetattr(). */ if (cmd == TIOCSETAW || cmd == TIOCSETAF) { @@ -1361,7 +1360,7 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td) /* XXX: CLOCAL? */ - tp->t_termios.c_cflag = t->c_cflag; + tp->t_termios.c_cflag = t->c_cflag & ~CIGNORE; tp->t_termios.c_ispeed = t->c_ispeed; tp->t_termios.c_ospeed = t->c_ospeed; |