diff options
author | jmallett <jmallett@FreeBSD.org> | 2002-10-01 00:07:28 +0000 |
---|---|---|
committer | jmallett <jmallett@FreeBSD.org> | 2002-10-01 00:07:28 +0000 |
commit | a8d86705cfc76b2c997e69114c1c0f8c049ec4da (patch) | |
tree | 9ac0bc441013807176f0e4681c2c5ae2da3657cd | |
parent | 3fbea8bffecb35fe18cb9bc9115b310594e105b9 (diff) | |
download | FreeBSD-src-a8d86705cfc76b2c997e69114c1c0f8c049ec4da.zip FreeBSD-src-a8d86705cfc76b2c997e69114c1c0f8c049ec4da.tar.gz |
(Forced commit, to clarify previous commit of ksiginfo/signal queue code.)
I've added a structure, kernel-private, to represent a pending or in-delivery
signal, called `ksiginfo'. It is roughly analogous to the basic information
that is exported by the POSIX interface 'siginfo_t', but more basic. I've
added functions to allocate these structures, and further to wrap all signal
operations using them.
Once the operations are wrapped, I've added a TailQ (see queue(3)) of these
structures to 'struct proc', and all pending signals are in that TailQ. When
a signal is being delivered, it is dequeued from the list. Once I finish
the spreading of ksiginfo throughout the tree, the dequeued structure will be
delivered to the process in question, whereas currently and normally, the
signal number is what is used.
-rw-r--r-- | sys/kern/kern_sig.c | 13 | ||||
-rw-r--r-- | sys/kern/subr_sigq.c | 17 | ||||
-rw-r--r-- | sys/sys/ksiginfo.h | 2 |
3 files changed, 28 insertions, 4 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index ada2016..5e42a7e 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1227,8 +1227,11 @@ trapsignal(p, sig, code) u_long code; { register struct sigacts *ps = p->p_sigacts; + struct ksiginfo *ksi; PROC_LOCK(p); + ksiginfo_alloc(&ksi, sig); + ksi->ksi_code = code; if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(p->p_sigcatch, sig) && !SIGISMEMBER(p->p_sigmask, sig)) { p->p_stats->p_ru.ru_nsignals++; @@ -1237,8 +1240,8 @@ trapsignal(p, sig, code) ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)], &p->p_sigmask, code); #endif - (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], sig, - &p->p_sigmask, code); + (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], ksi, + &p->p_sigmask); SIGSETOR(p->p_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]); if (!SIGISMEMBER(ps->ps_signodefer, sig)) SIGADDSET(p->p_sigmask, sig); @@ -1799,6 +1802,7 @@ postsig(sig) { struct thread *td = curthread; register struct proc *p = td->td_proc; + struct ksiginfo *ksi; struct sigacts *ps; sig_t action; sigset_t returnmask; @@ -1808,7 +1812,7 @@ postsig(sig) PROC_LOCK_ASSERT(p, MA_OWNED); ps = p->p_sigacts; - signal_delete(p, NULL, sig); + ksiginfo_dequeue(&ksi, p, sig); action = ps->ps_sigact[_SIG_IDX(sig)]; #ifdef KTRACE if (KTRPOINT(td, KTR_PSIG)) @@ -1822,6 +1826,7 @@ postsig(sig) * Default action, where the default is to kill * the process. (Other cases were ignored above.) */ + ksiginfo_destroy(&ksi); sigexit(td, sig); /* NOTREACHED */ } else { @@ -1870,7 +1875,7 @@ postsig(sig) if (p->p_flag & P_KSES) if (signal_upcall(p, sig)) return; - (*p->p_sysent->sv_sendsig)(action, sig, &returnmask, code); + (*p->p_sysent->sv_sendsig)(action, ksi, &returnmask); } } diff --git a/sys/kern/subr_sigq.c b/sys/kern/subr_sigq.c index fa44fab..cf5dd50 100644 --- a/sys/kern/subr_sigq.c +++ b/sys/kern/subr_sigq.c @@ -118,6 +118,23 @@ out: } int +ksiginfo_to_siginfo_t(struct ksiginfo *ksi, siginfo_t *si) +{ + int error; + + error = 0; + + si->si_addr = ksi->ksi_addr; + si->si_code = ksi->ksi_code; + si->si_errno = ksi->ksi_errno; + si->si_signo = ksi->ksi_errno; + si->si_status = ksi->ksi_status; + si->si_uid = ksi->ksi_ruid; + si->si_pid = ksi->ksi_pid; + return (error); +} + +int ksiginfo_to_sigset_t(struct proc *p, sigset_t *setp) { int error; diff --git a/sys/sys/ksiginfo.h b/sys/sys/ksiginfo.h index 26b88d5..40d9542 100644 --- a/sys/sys/ksiginfo.h +++ b/sys/sys/ksiginfo.h @@ -36,6 +36,7 @@ #endif #include <sys/malloc.h> +#include <sys/signal.h> /* * Structures and prototypes for working with the in-kernel representation @@ -66,6 +67,7 @@ __BEGIN_DECLS; int ksiginfo_alloc(struct ksiginfo **, int); int ksiginfo_dequeue(struct ksiginfo **, struct proc *, int); int ksiginfo_destroy(struct ksiginfo **); +int ksiginfo_to_siginfo_t(struct ksiginfo *, siginfo_t *); int ksiginfo_to_sigset_t(struct proc *, sigset_t *); int signal_add(struct proc *, struct ksiginfo *, int); int signal_delete(struct proc *, struct ksiginfo *, int); |