summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty_pty.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/tty_pty.c')
-rw-r--r--sys/kern/tty_pty.c85
1 files changed, 40 insertions, 45 deletions
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index 7cbb13a523a..6cb8615f724 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty_pty.c,v 1.14 2003/07/22 01:03:12 mickey Exp $ */
+/* $OpenBSD: tty_pty.c,v 1.15 2003/09/23 16:51:12 millert Exp $ */
/* $NetBSD: tty_pty.c,v 1.33.4.1 1996/06/02 09:08:11 mrg Exp $ */
/*
@@ -50,6 +50,7 @@
#include <sys/signalvar.h>
#include <sys/uio.h>
#include <sys/conf.h>
+#include <sys/poll.h>
#define BUFSIZ 100 /* Chunk size iomoved to/from user */
@@ -233,7 +234,7 @@ ptswrite(dev, uio, flag)
/*
* Start output on pseudo-tty.
- * Wake up process selecting or sleeping for input from controlling tty.
+ * Wake up process polling or sleeping for input from controlling tty.
*/
void
ptsstart(tp)
@@ -501,58 +502,52 @@ block:
}
int
-ptcselect(dev, rw, p)
- dev_t dev;
- int rw;
- struct proc *p;
+ptcpoll(dev_t dev, int events, struct proc *p)
{
- register struct pt_softc *pti = &pt_softc[minor(dev)];
- register struct tty *tp = pti->pt_tty;
- int s;
+ struct pt_softc *pti = &pt_softc[minor(dev)];
+ struct tty *tp = pti->pt_tty;
+ int revents = 0, s;
- if ((tp->t_state&TS_CARR_ON) == 0)
- return (1);
- switch (rw) {
+ if (!ISSET(tp->t_state, TS_CARR_ON))
+ return (POLLHUP);
+
+ if (!ISSET(tp->t_state, TS_ISOPEN))
+ goto notopen;
- case FREAD:
+ if (events & (POLLIN | POLLRDNORM)) {
/*
- * Need to block timeouts (ttrstart).
+ * Need to protect access to t_outq
*/
s = spltty();
- if ((tp->t_state&TS_ISOPEN) &&
- tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
- splx(s);
- return (1);
- }
+ if ((tp->t_outq.c_cc && !ISSET(tp->t_state, TS_TTSTOP)) ||
+ ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+ ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
+ revents |= events & (POLLIN | POLLRDNORM);
splx(s);
- /* FALLTHROUGH */
-
- case 0: /* exceptional */
- if ((tp->t_state&TS_ISOPEN) &&
- (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
- ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)))
- return (1);
- selrecord(p, &pti->pt_selr);
- break;
-
-
- case FWRITE:
- if (tp->t_state&TS_ISOPEN) {
- if (pti->pt_flags & PF_REMOTE) {
- if (tp->t_canq.c_cc == 0)
- return (1);
- } else {
- if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2)
- return (1);
- if (tp->t_canq.c_cc == 0 && ISSET(tp->t_lflag, ICANON))
- return (1);
- }
- }
- selrecord(p, &pti->pt_selw);
- break;
+ }
+ if (events & (POLLOUT | POLLWRNORM)) {
+ if ((pti->pt_flags & PF_REMOTE) ?
+ (tp->t_canq.c_cc == 0) :
+ ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
+ (tp->t_canq.c_cc == 0 && ISSET(tp->t_lflag, ICANON))))
+ revents |= events & (POLLOUT | POLLWRNORM);
+ }
+ if (events & (POLLPRI | POLLRDBAND)) {
+ /* If in packet or user control mode, check for data. */
+ if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+ ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
+ revents |= events & (POLLPRI | POLLRDBAND);
+ }
+ if (revents == 0) {
+notopen:
+ if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND))
+ selrecord(p, &pti->pt_selr);
+ if (events & (POLLOUT | POLLWRNORM))
+ selrecord(p, &pti->pt_selw);
}
- return (0);
+
+ return (revents);
}
void