diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2003-06-14 23:14:31 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2003-06-14 23:14:31 +0000 |
commit | e859d79f84fea4d3c3c2c73dc6dc041ddf6e942b (patch) | |
tree | 2ca90a45a38ec01ab34805009d067ed15a3976c1 | |
parent | 24608a6d889217166803cb86505cb1530107d10d (diff) |
doing kqueue on the master side of the pty returns events
for the slave size as described in the pr3209.
the regress has been created to verify for the conditions.
from wayne@epipe.com.au
-rw-r--r-- | sys/kern/tty_pty.c | 104 | ||||
-rw-r--r-- | sys/sys/conf.h | 4 |
2 files changed, 105 insertions, 3 deletions
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index bc78b928237..e8b8651247e 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty_pty.c,v 1.11 2003/06/02 23:28:06 millert Exp $ */ +/* $OpenBSD: tty_pty.c,v 1.12 2003/06/14 23:14:30 mickey Exp $ */ /* $NetBSD: tty_pty.c,v 1.33.4.1 1996/06/02 09:08:11 mrg Exp $ */ /* @@ -77,6 +77,11 @@ void ptcwakeup(struct tty *, int); struct tty *ptytty(dev_t); void ptsstart(struct tty *); +void filt_ptcrdetach(struct knote *); +int filt_ptcread(struct knote *, long); +void filt_ptcwdetach(struct knote *); +int filt_ptcwrite(struct knote *, long); + /* * Establish n (or default if n is 1) ptys in the system. */ @@ -280,10 +285,12 @@ ptcwakeup(tp, flag) if (flag & FREAD) { selwakeup(&pti->pt_selr); wakeup((caddr_t)&tp->t_outq.c_cf); + KNOTE(&pti->pt_selr.si_note, 0); } if (flag & FWRITE) { selwakeup(&pti->pt_selw); wakeup((caddr_t)&tp->t_rawq.c_cf); + KNOTE(&pti->pt_selw.si_note, 0); } } @@ -549,6 +556,101 @@ ptcselect(dev, rw, p) return (0); } +void +filt_ptcrdetach(struct knote *kn) +{ + struct pt_softc *pti = (struct pt_softc *)kn->kn_hook; + int s; + + s = spltty(); + SLIST_REMOVE(&pti->pt_selr.si_note, kn, knote, kn_selnext); + splx(s); +} + +int +filt_ptcread(struct knote *kn, long hint) +{ + struct pt_softc *pti = (struct pt_softc *)kn->kn_hook; + struct tty *tp; + + tp = pti->pt_tty; + kn->kn_data = 0; + + if (ISSET(tp->t_state, TS_ISOPEN)) { + if (!ISSET(tp->t_state, TS_TTSTOP)) + kn->kn_data = tp->t_outq.c_cc; + if (((pti->pt_flags & PF_PKT) && pti->pt_send) || + ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) + kn->kn_data++; + } + return (kn->kn_data > 0); +} + +void +filt_ptcwdetach(struct knote *kn) +{ + struct pt_softc *pti = (struct pt_softc *)kn->kn_hook; + int s; + + s = spltty(); + SLIST_REMOVE(&pti->pt_selw.si_note, kn, knote, kn_selnext); + splx(s); +} + +int +filt_ptcwrite(struct knote *kn, long hint) +{ + struct pt_softc *pti = (struct pt_softc *)kn->kn_hook; + struct tty *tp; + + tp = pti->pt_tty; + kn->kn_data = 0; + + if (ISSET(tp->t_state, TS_ISOPEN)) { + if (ISSET(pti->pt_flags, PF_REMOTE)) { + if (tp->t_canq.c_cc == 0) + kn->kn_data = tp->t_canq.c_cn; + } else if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2) + kn->kn_data = tp->t_canq.c_cn - + (tp->t_rawq.c_cc + tp->t_canq.c_cc); + } + + return (kn->kn_data > 0); +} + +struct filterops ptcread_filtops = + { 1, NULL, filt_ptcrdetach, filt_ptcread }; +struct filterops ptcwrite_filtops = + { 1, NULL, filt_ptcwdetach, filt_ptcwrite }; + +int +ptckqfilter(dev_t dev, struct knote *kn) +{ + struct pt_softc *pti = &pt_softc[minor(dev)]; + struct klist *klist; + int s; + + switch (kn->kn_filter) { + case EVFILT_READ: + klist = &pti->pt_selr.si_note; + kn->kn_fop = &ptcread_filtops; + break; + case EVFILT_WRITE: + klist = &pti->pt_selw.si_note; + kn->kn_fop = &ptcwrite_filtops; + break; + default: + return (1); + } + + kn->kn_hook = (caddr_t)pti; + + s = spltty(); + SLIST_INSERT_HEAD(klist, kn, kn_selnext); + splx(s); + + return (0); +} struct tty * ptytty(dev) diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 405242f6111..e4b8174fe93 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.h,v 1.69 2003/06/02 23:28:21 millert Exp $ */ +/* $OpenBSD: conf.h,v 1.70 2003/06/14 23:14:30 mickey Exp $ */ /* $NetBSD: conf.h,v 1.33 1996/05/03 20:03:32 christos Exp $ */ /*- @@ -273,7 +273,7 @@ extern struct cdevsw cdevsw[]; dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ dev_init(c,n,tty), dev_init(c,n,select), (dev_type_mmap((*))) enodev, \ - D_TTY | D_KQFILTER, ttkqfilter } + D_TTY | D_KQFILTER, dev_init(c,n,kqfilter) } /* open, close, read, ioctl, select, kqfilter -- XXX should be a generic device */ #define cdev_log_init(c,n) { \ |