diff options
author | ed <ed@FreeBSD.org> | 2008-08-29 15:02:50 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2008-08-29 15:02:50 +0000 |
commit | e9104ac4da86a621d908b1f70a1ae752c65b0df1 (patch) | |
tree | 7cae601a86cfbd8c8ad93f37761219439296d196 /sys/kern | |
parent | 9805322d6a54ac5764e627b535b4bf55828c2d70 (diff) | |
download | FreeBSD-src-e9104ac4da86a621d908b1f70a1ae752c65b0df1.zip FreeBSD-src-e9104ac4da86a621d908b1f70a1ae752c65b0df1.tar.gz |
Backport two small fixes from the MPSAFE TTY branch in Perforce:
- Implement IMAXBEL. It turned out the IMAXBEL termios switch was marked
as supported, while it had not been implemented.
- Don't go into the high watermark when in canonical mode, no data has
been canonicalized and the input buffer is full. This caused the
terminal to lock up. This prevented users from pressing
backspace/^U/etc in such cases.
This could easily be simulated by pasting a very big amount of data in
a shell with sh(1) in canonical mode.
Obtained from: //depot/projects/mpsafetty/...
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/tty_ttydisc.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/kern/tty_ttydisc.c b/sys/kern/tty_ttydisc.c index b52fc18..6244166 100644 --- a/sys/kern/tty_ttydisc.c +++ b/sys/kern/tty_ttydisc.c @@ -305,7 +305,6 @@ int ttydisc_read(struct tty *tp, struct uio *uio, int ioflag) { int error; - size_t c; tty_lock_assert(tp, MA_OWNED); @@ -322,8 +321,8 @@ ttydisc_read(struct tty *tp, struct uio *uio, int ioflag) else error = ttydisc_read_raw_interbyte_timer(tp, uio, ioflag); - c = ttyinq_bytesleft(&tp->t_inq); - if (c >= tp->t_inlow) { + if (ttyinq_bytesleft(&tp->t_inq) >= tp->t_inlow || + ttyinq_bytescanonicalized(&tp->t_inq) == 0) { /* Unset the input watermark when we've got enough space. */ tty_hiwat_in_unblock(tp); } @@ -1001,7 +1000,20 @@ parmrk: print: /* See if we can store this on the input queue. */ if (ttyinq_write_nofrag(&tp->t_inq, ob, ol, quote) != 0) { - /* We cannot. Enable the input watermark. */ + if (CMP_FLAG(i, IMAXBEL)) + ttyoutq_write_nofrag(&tp->t_outq, "\a", 1); + + /* + * Prevent a deadlock here. It may be possible that a + * user has entered so much data, there is no data + * available to read(), but the buffers are full anyway. + * + * Only enter the high watermark if the device driver + * can actually transmit something. + */ + if (ttyinq_bytescanonicalized(&tp->t_inq) == 0) + return (0); + tty_hiwat_in_block(tp); return (-1); } |