summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-08-02 14:25:26 +0000
committered <ed@FreeBSD.org>2009-08-02 14:25:26 +0000
commitea03af42ccd07d2533707afe4d1ba08f34bdb2e9 (patch)
tree83f37a3195c24783ffcfba938ae2aefa103541ad
parentc5b1acbb23e59bea7d9025852bb9c14a0bc5b69a (diff)
downloadFreeBSD-src-ea03af42ccd07d2533707afe4d1ba08f34bdb2e9.zip
FreeBSD-src-ea03af42ccd07d2533707afe4d1ba08f34bdb2e9.tar.gz
Fix two bugs related to TTY input:
- fix write() on pseudo-terminal masters to return the amount of bytes passed to the TTY, not the amount of bytes read from user. - fix ttydisc_rint_bypass() to set the high watermark when it cannot write all input, just like ttydisc_rint() itself. Approved by: re (kib)
-rw-r--r--sys/kern/tty_pts.c10
-rw-r--r--sys/kern/tty_ttydisc.c2
2 files changed, 11 insertions, 1 deletions
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index 999472a..d5045c1 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -204,8 +204,10 @@ ptsdev_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
error = uiomove(ib, iblen, uio);
tty_lock(tp);
- if (error != 0)
+ if (error != 0) {
+ iblen = 0;
goto done;
+ }
/*
* When possible, avoid the slow path. rint_bypass()
@@ -260,6 +262,12 @@ ptsdev_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
done: ttydisc_rint_done(tp);
tty_unlock(tp);
+
+ /*
+ * Don't account for the part of the buffer that we couldn't
+ * pass to the TTY.
+ */
+ uio->uio_resid += iblen;
return (error);
}
diff --git a/sys/kern/tty_ttydisc.c b/sys/kern/tty_ttydisc.c
index 634b58e..debaa1c 100644
--- a/sys/kern/tty_ttydisc.c
+++ b/sys/kern/tty_ttydisc.c
@@ -1060,6 +1060,8 @@ ttydisc_rint_bypass(struct tty *tp, const void *buf, size_t len)
ret = ttyinq_write(&tp->t_inq, buf, len, 0);
ttyinq_canonicalize(&tp->t_inq);
+ if (ret < len)
+ tty_hiwat_in_block(tp);
return (ret);
}
OpenPOWER on IntegriCloud