summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2008-08-29 15:02:50 +0000
committered <ed@FreeBSD.org>2008-08-29 15:02:50 +0000
commite9104ac4da86a621d908b1f70a1ae752c65b0df1 (patch)
tree7cae601a86cfbd8c8ad93f37761219439296d196 /sys
parent9805322d6a54ac5764e627b535b4bf55828c2d70 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/kern/tty_ttydisc.c20
-rw-r--r--sys/sys/ttydisc.h17
2 files changed, 29 insertions, 8 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);
}
diff --git a/sys/sys/ttydisc.h b/sys/sys/ttydisc.h
index dd170e6..0d43666 100644
--- a/sys/sys/ttydisc.h
+++ b/sys/sys/ttydisc.h
@@ -84,10 +84,19 @@ ttydisc_write_poll(struct tty *tp)
static __inline size_t
ttydisc_rint_poll(struct tty *tp)
{
-
- tty_lock_assert(tp, MA_OWNED);
-
- return ttyinq_bytesleft(&tp->t_inq);
+ size_t l;
+
+ /*
+ * XXX: Still allow character input when there's no space in the
+ * buffers, but we haven't entered the high watermark. This is
+ * to allow backspace characters to be inserted when in
+ * canonical mode.
+ */
+ l = ttyinq_bytesleft(&tp->t_inq);
+ if (l == 0 && (tp->t_flags & TF_HIWAT_IN) == 0)
+ return (1);
+
+ return (l);
}
static __inline size_t
OpenPOWER on IntegriCloud