summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) { \