diff options
author | ed <ed@FreeBSD.org> | 2009-07-08 10:21:52 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-07-08 10:21:52 +0000 |
commit | 82187ebf4442997e887a1eb21292f91962a323e1 (patch) | |
tree | 47476acfa61996cc932ee81e1e9cdbc464267dee /sys/kern/tty.c | |
parent | 446d01edc9ebdb046bfd5a9127af3886d4f871fc (diff) | |
download | FreeBSD-src-82187ebf4442997e887a1eb21292f91962a323e1.zip FreeBSD-src-82187ebf4442997e887a1eb21292f91962a323e1.tar.gz |
Fix regressions in return events of poll() on TTYs.
As pointed out, POLLHUP should be generated, even if it hasn't been
specified on input. It is also not allowed to return both POLLOUT and
POLLHUP at the same time.
Reported by: jilles
Approved by: re (kib)
Diffstat (limited to 'sys/kern/tty.c')
-rw-r--r-- | sys/kern/tty.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c index d8a76d9..a14f714 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -536,25 +536,23 @@ ttydev_poll(struct cdev *dev, int events, struct thread *td) int error, revents = 0; error = ttydev_enter(tp); - if (error) { - /* Don't return the error here, but the event mask. */ - return (events & - (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM)); - } + if (error) + return ((events & (POLLIN|POLLRDNORM)) | POLLHUP); if (events & (POLLIN|POLLRDNORM)) { /* See if we can read something. */ if (ttydisc_read_poll(tp) > 0) revents |= events & (POLLIN|POLLRDNORM); } - if (events & (POLLOUT|POLLWRNORM)) { + + if (tp->t_flags & TF_ZOMBIE) { + /* Hangup flag on zombie state. */ + revents |= POLLHUP; + } else if (events & (POLLOUT|POLLWRNORM)) { /* See if we can write something. */ if (ttydisc_write_poll(tp) > 0) revents |= events & (POLLOUT|POLLWRNORM); } - if (tp->t_flags & TF_ZOMBIE) - /* Hangup flag on zombie state. */ - revents |= events & POLLHUP; if (revents == 0) { if (events & (POLLIN|POLLRDNORM)) |