aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/tty.c
diff options
context:
space:
mode:
authorJonathan Lemon <jlemon@FreeBSD.org>2001-02-15 16:34:11 +0000
committerJonathan Lemon <jlemon@FreeBSD.org>2001-02-15 16:34:11 +0000
commit608a3ce62a98c42e5d415af6d6dc98f2bf4e615b (patch)
treea9aab1f038a4aab4a0d31919948c7c964e5b85d6 /sys/kern/tty.c
parent2c9ba841c61cbced165336bd4e2b21be82cfdcd0 (diff)
downloadsrc-608a3ce62a98c42e5d415af6d6dc98f2bf4e615b.tar.gz
src-608a3ce62a98c42e5d415af6d6dc98f2bf4e615b.zip
Extend kqueue down to the device layer.
Backwards compatible approach suggested by: peter
Notes
Notes: svn path=/head/; revision=72521
Diffstat (limited to 'sys/kern/tty.c')
-rw-r--r--sys/kern/tty.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index b815e7c75d5a..b5b8a9cd13b8 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -113,6 +113,10 @@ static void ttyrub __P((int c, struct tty *tp));
static void ttyrubo __P((struct tty *tp, int cnt));
static void ttyunblock __P((struct tty *tp));
static int ttywflush __P((struct tty *tp));
+static int filt_ttyread __P((struct knote *kn, long hint));
+static void filt_ttyrdetach __P((struct knote *kn));
+static int filt_ttywrite __P((struct knote *kn, long hint));
+static void filt_ttywdetach __P((struct knote *kn));
/*
* Table with character classes and parity. The 8th bit indicates parity,
@@ -1092,6 +1096,89 @@ ttypoll(dev, events, p)
return (revents);
}
+static struct filterops ttyread_filtops =
+ { 1, NULL, filt_ttyrdetach, filt_ttyread };
+static struct filterops ttywrite_filtops =
+ { 1, NULL, filt_ttywdetach, filt_ttywrite };
+
+int
+ttykqfilter(dev, kn)
+ dev_t dev;
+ struct knote *kn;
+{
+ struct tty *tp = dev->si_tty;
+ struct klist *klist;
+ int s;
+
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ klist = &tp->t_rsel.si_note;
+ kn->kn_fop = &ttyread_filtops;
+ break;
+ case EVFILT_WRITE:
+ klist = &tp->t_wsel.si_note;
+ kn->kn_fop = &ttywrite_filtops;
+ break;
+ default:
+ return (1);
+ }
+
+ kn->kn_hook = (caddr_t)dev;
+
+ s = spltty();
+ SLIST_INSERT_HEAD(klist, kn, kn_selnext);
+ splx(s);
+
+ return (0);
+}
+
+static void
+filt_ttyrdetach(struct knote *kn)
+{
+ struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
+ int s = spltty();
+
+ SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext);
+ splx(s);
+}
+
+static int
+filt_ttyread(struct knote *kn, long hint)
+{
+ struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
+
+ kn->kn_data = ttnread(tp);
+ if (ISSET(tp->t_state, TS_ZOMBIE)) {
+ kn->kn_flags |= EV_EOF;
+ return (1);
+ }
+ return (kn->kn_data > 0);
+}
+
+static void
+filt_ttywdetach(struct knote *kn)
+{
+ struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
+ int s = spltty();
+
+ SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext);
+ splx(s);
+}
+
+static int
+filt_ttywrite(kn, hint)
+ struct knote *kn;
+ long hint;
+{
+ struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
+
+ kn->kn_data = tp->t_outq.c_cc;
+ if (ISSET(tp->t_state, TS_ZOMBIE))
+ return (1);
+ return (kn->kn_data <= tp->t_olowat &&
+ ISSET(tp->t_state, TS_CONNECTED));
+}
+
/*
* Must be called at spltty().
*/
@@ -2118,6 +2205,7 @@ ttwakeup(tp)
if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
wakeup(TSA_HUP_OR_INPUT(tp));
+ KNOTE(&tp->t_rsel.si_note, 0);
}
/*
@@ -2142,6 +2230,7 @@ ttwwakeup(tp)
CLR(tp->t_state, TS_SO_OLOWAT);
wakeup(TSA_OLOWAT(tp));
}
+ KNOTE(&tp->t_wsel.si_note, 0);
}
/*