diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2024-07-29 12:42:54 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2024-07-29 12:42:54 +0000 |
commit | 2fc3f525a558a776b164e80cf7a7b133a0f8262f (patch) | |
tree | 1d5f267b7025c38b3b2a562eac2266f4b585d7ca /sys/kern/kern_event.c | |
parent | b02e5b79651e29b9d52b0cab29f202016f62ba00 (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.c | 61 |
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) |