summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2003-06-14 23:14:31 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2003-06-14 23:14:31 +0000
commite859d79f84fea4d3c3c2c73dc6dc041ddf6e942b (patch)
tree2ca90a45a38ec01ab34805009d067ed15a3976c1
parent24608a6d889217166803cb86505cb1530107d10d (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.c104
-rw-r--r--sys/sys/conf.h4
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) { \