summaryrefslogtreecommitdiff
path: root/sys/kern/kern_event.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2024-07-29 12:42:54 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2024-07-29 12:42:54 +0000
commit2fc3f525a558a776b164e80cf7a7b133a0f8262f (patch)
tree1d5f267b7025c38b3b2a562eac2266f4b585d7ca /sys/kern/kern_event.c
parentb02e5b79651e29b9d52b0cab29f202016f62ba00 (diff)
Move the signal related kqueue filters to kern_event.c.
Since proc and signal filters share the same klist it makes sense to keep them together. OK mvs@
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r--sys/kern/kern_event.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 7e3ae6eae3a..e2c99fe1e78 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.198 2023/08/20 15:13:43 visa Exp $ */
+/* $OpenBSD: kern_event.c,v 1.199 2024/07/29 12:42:53 claudio Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -124,6 +124,9 @@ int filt_kqueue_common(struct knote *kn, struct kqueue *kq);
int filt_procattach(struct knote *kn);
void filt_procdetach(struct knote *kn);
int filt_proc(struct knote *kn, long hint);
+int filt_sigattach(struct knote *kn);
+void filt_sigdetach(struct knote *kn);
+int filt_signal(struct knote *kn, long hint);
int filt_fileattach(struct knote *kn);
void filt_timerexpire(void *knx);
int filt_timerattach(struct knote *kn);
@@ -148,6 +151,13 @@ const struct filterops proc_filtops = {
.f_event = filt_proc,
};
+const struct filterops sig_filtops = {
+ .f_flags = 0,
+ .f_attach = filt_sigattach,
+ .f_detach = filt_sigdetach,
+ .f_event = filt_signal,
+};
+
const struct filterops file_filtops = {
.f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
.f_attach = filt_fileattach,
@@ -450,6 +460,55 @@ filt_proc(struct knote *kn, long hint)
return (kn->kn_fflags != 0);
}
+/*
+ * 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.
+ */
+int
+filt_sigattach(struct knote *kn)
+{
+ struct process *pr = curproc->p_p;
+ int s;
+
+ if (kn->kn_id >= NSIG)
+ return EINVAL;
+
+ kn->kn_ptr.p_process = pr;
+ kn->kn_flags |= EV_CLEAR; /* automatically set */
+
+ s = splhigh();
+ klist_insert_locked(&pr->ps_klist, kn);
+ splx(s);
+
+ return (0);
+}
+
+void
+filt_sigdetach(struct knote *kn)
+{
+ struct process *pr = kn->kn_ptr.p_process;
+ int s;
+
+ s = splhigh();
+ klist_remove_locked(&pr->ps_klist, kn);
+ splx(s);
+}
+
+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);
+}
+
#define NOTE_TIMER_UNITMASK \
(NOTE_SECONDS|NOTE_MSECONDS|NOTE_USECONDS|NOTE_NSECONDS)