summaryrefslogtreecommitdiffstats
path: root/sys
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 /sys
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.
Diffstat (limited to 'sys')
-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