summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2000-04-16 18:53:38 +0000
committerjlemon <jlemon@FreeBSD.org>2000-04-16 18:53:38 +0000
commitc41c876463ee8c302f06554537e0fb22a3fcdca4 (patch)
treed2f87a6af04c4f35f243bf580d099496a4131330 /sys/kern/kern_sig.c
parentf8f9ad64d408b963d98d0e11b37e871763557e95 (diff)
downloadFreeBSD-src-c41c876463ee8c302f06554537e0fb22a3fcdca4.zip
FreeBSD-src-c41c876463ee8c302f06554537e0fb22a3fcdca4.tar.gz
Introduce kqueue() and kevent(), a kernel event notification facility.
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index e3e0e59..52136d6 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -49,6 +49,7 @@
#include <sys/resourcevar.h>
#include <sys/namei.h>
#include <sys/vnode.h>
+#include <sys/event.h>
#include <sys/proc.h>
#include <sys/pioctl.h>
#include <sys/systm.h>
@@ -81,6 +82,13 @@ static int sig_ffs __P((sigset_t *set));
static int sigprop __P((int sig));
static void stop __P((struct proc *));
+static int filt_sigattach(struct knote *kn);
+static void filt_sigdetach(struct knote *kn);
+static int filt_signal(struct knote *kn, long hint);
+
+struct filterops sig_filtops =
+ { 0, filt_sigattach, filt_sigdetach, filt_signal };
+
static int kern_logsigexit = 1;
SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW,
&kern_logsigexit, 0,
@@ -1002,6 +1010,8 @@ psignal(p, sig)
panic("psignal signal number");
}
+ KNOTE(&p->p_klist, NOTE_SIGNAL | sig);
+
prop = sigprop(sig);
/*
@@ -1688,3 +1698,44 @@ pgsigio(sigio, sig, checkctty)
psignal(p, sig);
}
}
+
+static int
+filt_sigattach(struct knote *kn)
+{
+ struct proc *p = curproc;
+
+ kn->kn_ptr.p_proc = p;
+ kn->kn_flags |= EV_CLEAR; /* automatically set */
+
+ /* XXX lock the proc here while adding to the list? */
+ SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext);
+
+ return (0);
+}
+
+static void
+filt_sigdetach(struct knote *kn)
+{
+ struct proc *p = kn->kn_ptr.p_proc;
+
+ SLIST_REMOVE(&p->p_klist, kn, knote, kn_selnext);
+}
+
+/*
+ * signal knotes are shared with proc knotes, so we apply a mask to
+ * the hint in order to differentiate them from process hints. This
+ * could be avoided by using a signal-specific knote list, but probably
+ * isn't worth the trouble.
+ */
+static int
+filt_signal(struct knote *kn, long hint)
+{
+
+ if (hint & NOTE_SIGNAL) {
+ hint &= ~NOTE_SIGNAL;
+
+ if (kn->kn_id == hint)
+ kn->kn_data++;
+ }
+ return (kn->kn_data != 0);
+}
OpenPOWER on IntegriCloud