#include <sys/signalvar.h>
#include <sys/kernel.h>
#include <sys/poll.h>
+#include <sys/event.h>
#include <sys/filedesc.h>
#include <sys/sysctl.h>
#include <sys/thread2.h>
static d_read_t logread;
static d_ioctl_t logioctl;
static d_poll_t logpoll;
+static d_kqfilter_t logkqfilter;
static void logtimeout(void *arg);
+static void logfiltdetach(struct knote *kn);
+static int logfiltread(struct knote *kn, long hint);
#define CDEV_MAJOR 7
static struct dev_ops log_ops = {
- { "log", CDEV_MAJOR, 0 },
+ { "log", CDEV_MAJOR, D_KQFILTER },
.d_open = logopen,
.d_close = logclose,
.d_read = logread,
.d_ioctl = logioctl,
.d_poll = logpoll,
+ .d_kqfilter = logkqfilter
};
static struct logsoftc {
return (0);
}
+static struct filterops logread_filtops =
+ { 1, NULL, logfiltdetach, logfiltread };
+
+static int
+logkqfilter(struct dev_kqfilter_args *ap)
+{
+ struct knote *kn = ap->a_kn;
+ struct klist *klist = &logsoftc.sc_selp.si_note;
+
+ ap->a_result = 0;
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &logread_filtops;
+ break;
+ default:
+ ap->a_result = 1;
+ return (0);
+ }
+
+ crit_enter();
+ SLIST_INSERT_HEAD(klist, kn, kn_selnext);
+ crit_exit();
+
+ return (0);
+}
+
+static void
+logfiltdetach(struct knote *kn)
+{
+ struct klist *klist = &logsoftc.sc_selp.si_note;
+
+ crit_enter();
+ SLIST_REMOVE(klist, kn, knote, kn_selnext);
+ crit_exit();
+}
+
+static int
+logfiltread(struct knote *kn, long hint)
+{
+ int ret = 0;
+
+ crit_enter();
+ if (msgbufp->msg_bufr != msgbufp->msg_bufx)
+ ret = 1;
+ crit_exit();
+
+ return (ret);
+}
+
static void
logtimeout(void *arg)
{