diff options
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r-- | sys/kern/kern_sig.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index bb5c923f364..08a902b8c32 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.39 2000/11/10 18:15:47 art Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.40 2000/11/16 20:02:17 provos Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -46,8 +46,10 @@ #include <sys/param.h> #include <sys/signalvar.h> #include <sys/resourcevar.h> +#include <sys/queue.h> #include <sys/namei.h> #include <sys/vnode.h> +#include <sys/event.h> #include <sys/proc.h> #include <sys/systm.h> #include <sys/timeb.h> @@ -75,6 +77,13 @@ #include <uvm/uvm_extern.h> #endif +int filt_sigattach(struct knote *kn); +void filt_sigdetach(struct knote *kn); +int filt_signal(struct knote *kn, long hint); + +struct filterops sig_filtops = + { 0, filt_sigattach, filt_sigdetach, filt_signal }; + void stop __P((struct proc *p)); void killproc __P((struct proc *, char *)); int cansignal __P((struct proc *, struct pcred *, struct proc *, int)); @@ -683,6 +692,9 @@ psignal(p, signum) if ((u_int)signum >= NSIG || signum == 0) panic("psignal signal number"); + + KNOTE(&p->p_klist, NOTE_SIGNAL | signum); + mask = sigmask(signum); prop = sigprop[signum]; @@ -1331,3 +1343,44 @@ initsiginfo(si, sig, code, type, val) } } } + +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); +} + +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. + */ +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); +} |