summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2002-10-01 00:07:28 +0000
committerjmallett <jmallett@FreeBSD.org>2002-10-01 00:07:28 +0000
commita8d86705cfc76b2c997e69114c1c0f8c049ec4da (patch)
tree9ac0bc441013807176f0e4681c2c5ae2da3657cd
parent3fbea8bffecb35fe18cb9bc9115b310594e105b9 (diff)
downloadFreeBSD-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.c13
-rw-r--r--sys/kern/subr_sigq.c17
-rw-r--r--sys/sys/ksiginfo.h2
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);
OpenPOWER on IntegriCloud