signal(9) code: add some comments, improve/fix wrong ones. While here, kill

trailing whitespaces, wrap long lines, etc.  No functional changes intended.
This commit is contained in:
rmind 2009-12-20 04:49:09 +00:00
parent c628fa1620
commit 3c74cdf150
2 changed files with 154 additions and 172 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_sig.c,v 1.300 2009/11/14 19:06:54 rmind Exp $ */
/* $NetBSD: kern_sig.c,v 1.301 2009/12/20 04:49:09 rmind Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.300 2009/11/14 19:06:54 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.301 2009/12/20 04:49:09 rmind Exp $");
#include "opt_ptrace.h"
#include "opt_compat_sunos.h"
@ -125,8 +125,8 @@ int (*coredump_vec)(struct lwp *, const char *) =
(int (*)(struct lwp *, const char *))enosys;
static struct pool_allocator sigactspool_allocator = {
.pa_alloc = sigacts_poolpage_alloc,
.pa_free = sigacts_poolpage_free,
.pa_alloc = sigacts_poolpage_alloc,
.pa_free = sigacts_poolpage_free
};
#ifdef DEBUG
@ -135,9 +135,9 @@ int kern_logsigexit = 1;
int kern_logsigexit = 0;
#endif
static const char logcoredump[] =
static const char logcoredump[] =
"pid %d (%s), uid %d: exited on signal %d (core dumped)\n";
static const char lognocoredump[] =
static const char lognocoredump[] =
"pid %d (%s), uid %d: exited on signal %d (core not dumped, err = %d)\n";
static kauth_listener_t signal_listener;
@ -166,7 +166,7 @@ signal_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
/*
* signal_init:
*
* Initialize global signal-related data structures.
* Initialize global signal-related data structures.
*/
void
signal_init(void)
@ -196,14 +196,14 @@ signal_init(void)
/*
* sigacts_poolpage_alloc:
*
* Allocate a page for the sigacts memory pool.
* Allocate a page for the sigacts memory pool.
*/
static void *
sigacts_poolpage_alloc(struct pool *pp, int flags)
{
return (void *)uvm_km_alloc(kernel_map,
(PAGE_SIZE)*2, (PAGE_SIZE)*2,
PAGE_SIZE * 2, PAGE_SIZE * 2,
((flags & PR_WAITOK) ? 0 : UVM_KMF_NOWAIT | UVM_KMF_TRYLOCK)
| UVM_KMF_WIRED);
}
@ -211,21 +211,21 @@ sigacts_poolpage_alloc(struct pool *pp, int flags)
/*
* sigacts_poolpage_free:
*
* Free a page on behalf of the sigacts memory pool.
* Free a page on behalf of the sigacts memory pool.
*/
static void
sigacts_poolpage_free(struct pool *pp, void *v)
{
uvm_km_free(kernel_map, (vaddr_t)v, (PAGE_SIZE)*2, UVM_KMF_WIRED);
uvm_km_free(kernel_map, (vaddr_t)v, PAGE_SIZE * 2, UVM_KMF_WIRED);
}
/*
* sigactsinit:
*
* Create an initial sigctx structure, using the same signal state as
* p. If 'share' is set, share the sigctx_proc part, otherwise just
* copy it from parent.
*
* Create an initial sigacts structure, using the same signal state
* as of specified process. If 'share' is set, share the sigacts by
* holding a reference, otherwise just copy it from parent.
*/
struct sigacts *
sigactsinit(struct proc *pp, int share)
@ -253,9 +253,8 @@ sigactsinit(struct proc *pp, int share)
/*
* sigactsunshare:
*
* Make this process not share its sigctx, maintaining all
* signal state.
*
* Make this process not share its sigacts, maintaining all signal state.
*/
void
sigactsunshare(struct proc *p)
@ -276,7 +275,7 @@ sigactsunshare(struct proc *p)
/*
* sigactsfree;
*
* Release a sigctx structure.
* Release a sigacts structure.
*/
void
sigactsfree(struct sigacts *ps)
@ -450,7 +449,7 @@ ksiginfo_alloc(struct proc *p, ksiginfo_t *ok, int flags)
if (ok != NULL) {
if ((ok->ksi_flags & (KSI_QUEUED | KSI_FROMPOOL)) ==
KSI_FROMPOOL)
return ok;
return ok;
if (KSI_EMPTY_P(ok))
return ok;
}
@ -519,7 +518,7 @@ ksiginfo_queue_drain0(ksiginfoq_t *kq)
int
sigget(sigpend_t *sp, ksiginfo_t *out, int signo, const sigset_t *mask)
{
ksiginfo_t *ksi;
ksiginfo_t *ksi;
sigset_t tset;
/* If there's no pending set, the signal is from the debugger. */
@ -533,8 +532,8 @@ sigget(sigpend_t *sp, ksiginfo_t *out, int signo, const sigset_t *mask)
__sigandset(&sp->sp_set, &tset);
} else
tset = sp->sp_set;
/* If there are no signals pending, that's it. */
/* If there are no signals pending - return. */
if ((signo = firstsig(&tset)) == 0)
goto out;
} else {
@ -545,34 +544,32 @@ sigget(sigpend_t *sp, ksiginfo_t *out, int signo, const sigset_t *mask)
/* Find siginfo and copy it out. */
CIRCLEQ_FOREACH(ksi, &sp->sp_info, ksi_list) {
if (ksi->ksi_signo == signo) {
CIRCLEQ_REMOVE(&sp->sp_info, ksi, ksi_list);
KASSERT((ksi->ksi_flags & KSI_FROMPOOL) != 0);
KASSERT((ksi->ksi_flags & KSI_QUEUED) != 0);
ksi->ksi_flags &= ~KSI_QUEUED;
if (out != NULL) {
memcpy(out, ksi, sizeof(*out));
out->ksi_flags &= ~(KSI_FROMPOOL | KSI_QUEUED);
}
ksiginfo_free(ksi);
return signo;
if (ksi->ksi_signo != signo)
continue;
CIRCLEQ_REMOVE(&sp->sp_info, ksi, ksi_list);
KASSERT((ksi->ksi_flags & KSI_FROMPOOL) != 0);
KASSERT((ksi->ksi_flags & KSI_QUEUED) != 0);
ksi->ksi_flags &= ~KSI_QUEUED;
if (out != NULL) {
memcpy(out, ksi, sizeof(*out));
out->ksi_flags &= ~(KSI_FROMPOOL | KSI_QUEUED);
}
ksiginfo_free(ksi); /* XXXSMP */
return signo;
}
out:
/* If there's no siginfo, then manufacture it. */
/* If there is no siginfo, then manufacture it. */
if (out != NULL) {
KSI_INIT(out);
out->ksi_info._signo = signo;
out->ksi_info._code = SI_NOINFO;
}
return signo;
}
/*
* sigput:
*
*
* Append a new ksiginfo element to the list of pending ksiginfo's.
*/
static void
@ -687,10 +684,12 @@ sigispending(struct lwp *l, int signo)
return 0;
}
#ifdef KERN_SA
/*
* siginfo_alloc:
*
* Allocate a new siginfo_t structure from the pool.
* Allocate a new siginfo_t structure from the pool.
*/
siginfo_t *
siginfo_alloc(int flags)
@ -702,7 +701,7 @@ siginfo_alloc(int flags)
/*
* siginfo_free:
*
* Return a siginfo_t structure to the pool.
* Return a siginfo_t structure to the pool.
*/
void
siginfo_free(void *arg)
@ -711,6 +710,8 @@ siginfo_free(void *arg)
pool_cache_put(siginfo_cache, arg);
}
#endif
void
getucontext(struct lwp *l, ucontext_t *ucp)
{
@ -818,8 +819,7 @@ setucontext(struct lwp *l, const ucontext_t *ucp)
}
/*
* Common code for kill process group/broadcast kill. cp is calling
* process.
* killpg1: common code for kill process group/broadcast kill.
*/
int
killpg1(struct lwp *l, ksiginfo_t *ksi, int pgid, int all)
@ -837,7 +837,7 @@ killpg1(struct lwp *l, ksiginfo_t *ksi, int pgid, int all)
mutex_enter(proc_lock);
if (all) {
/*
* broadcast
* Broadcast.
*/
PROCLIST_FOREACH(p, &allproc) {
if (p->p_pid <= 1 || p == cp ||
@ -855,9 +855,7 @@ killpg1(struct lwp *l, ksiginfo_t *ksi, int pgid, int all)
}
} else {
if (pgid == 0)
/*
* zero pgid means send to my process group.
*/
/* Zero pgid means send to my process group. */
pgrp = cp->p_pgrp;
else {
pgrp = pg_find(pgid, PFIND_LOCKED);
@ -877,13 +875,13 @@ killpg1(struct lwp *l, ksiginfo_t *ksi, int pgid, int all)
mutex_exit(p->p_lock);
}
}
out:
out:
mutex_exit(proc_lock);
return (nfound ? 0 : ESRCH);
return nfound ? 0 : ESRCH;
}
/*
* Send a signal to a process group. If checktty is 1, limit to members
* Send a signal to a process group. If checktty is set, limit to members
* which have a controlling terminal.
*/
void
@ -906,9 +904,8 @@ kpgsignal(struct pgrp *pgrp, ksiginfo_t *ksi, void *data, int checkctty)
KASSERT(!cpu_intr_p());
KASSERT(mutex_owned(proc_lock));
KASSERT(pgrp != NULL);
if (__predict_false(pgrp == 0))
return;
LIST_FOREACH(p, &pgrp->pg_members, p_pglist)
if (checkctty == 0 || p->p_lflag & PL_CONTROLT)
kpsignal(p, ksi, data);
@ -943,8 +940,7 @@ trapsignal(struct lwp *l, ksiginfo_t *ksi)
l->l_ru.ru_nsignals++;
kpsendsig(l, ksi, mask);
mutex_exit(p->p_lock);
ktrpsig(signo, SIGACTION_PS(ps, signo).sa_handler,
mask, ksi);
ktrpsig(signo, SIGACTION_PS(ps, signo).sa_handler, mask, ksi);
} else {
/* XXX for core dump/debugger */
p->p_sigctx.ps_lwp = l->l_lid;
@ -1043,7 +1039,7 @@ kpsignal(struct proc *p, ksiginfo_t *ksi, void *data)
/*
* sigismasked:
*
* Returns true if signal is ignored or masked for the specified LWP.
* Returns true if signal is ignored or masked for the specified LWP.
*/
int
sigismasked(struct lwp *l, int sig)
@ -1061,8 +1057,8 @@ sigismasked(struct lwp *l, int sig)
/*
* sigpost:
*
* Post a pending signal to an LWP. Returns non-zero if the LWP may
* be able to take the signal.
* Post a pending signal to an LWP. Returns non-zero if the LWP may
* be able to take the signal.
*/
static int
sigpost(struct lwp *l, sig_t action, int prop, int sig, int idlecheck)
@ -1259,15 +1255,13 @@ sigunwait(struct proc *p, const ksiginfo_t *ksi)
void
kpsignal2(struct proc *p, ksiginfo_t *ksi)
{
int prop, lid, toall, signo = ksi->ksi_signo;
int prop, signo = ksi->ksi_signo;
struct sigacts *sa;
struct lwp *l;
ksiginfo_t *kp;
ksiginfoq_t kq;
lwpid_t lid;
sig_t action;
#ifdef KERN_SA
struct sadata_vp *vp;
#endif
bool toall;
KASSERT(!cpu_intr_p());
KASSERT(mutex_owned(proc_lock));
@ -1284,7 +1278,7 @@ kpsignal2(struct proc *p, ksiginfo_t *ksi)
/*
* Notify any interested parties of the signal.
*/
*/
KNOTE(&p->p_klist, NOTE_SIGNAL | signo);
/*
@ -1293,11 +1287,7 @@ kpsignal2(struct proc *p, ksiginfo_t *ksi)
kp = NULL;
prop = sigprop[signo];
toall = ((prop & SA_TOALL) != 0);
if (toall)
lid = 0;
else
lid = ksi->ksi_lid;
lid = toall ? 0 : ksi->ksi_lid;
/*
* If proc is traced, always give parent a chance.
@ -1362,6 +1352,8 @@ kpsignal2(struct proc *p, ksiginfo_t *ksi)
* signals that would do the inverse.
*/
if ((prop & (SA_CONT | SA_STOP)) != 0) {
ksiginfoq_t kq;
ksiginfo_queue_init(&kq);
if ((prop & SA_CONT) != 0)
sigclear(&p->p_sigpend, &stopsigmask, &kq);
@ -1464,7 +1456,7 @@ kpsignal2(struct proc *p, ksiginfo_t *ksi)
KASSERT((p->p_slflag & PSL_TRACED) == 0);
sigput(&p->p_sigpend, p, kp);
deliver:
deliver:
/*
* Before we set LW_PENDSIG on any LWP, ensure that the signal is
* visible on the per process list (for sigispending()). This
@ -1477,6 +1469,7 @@ kpsignal2(struct proc *p, ksiginfo_t *ksi)
*/
#if KERN_SA
if ((p->p_sa != NULL) && !toall) {
struct sadata_vp *vp;
/*
* If we're in this delivery path, we are delivering a
* signal that needs to go to one thread in the process.
@ -1501,20 +1494,20 @@ kpsignal2(struct proc *p, ksiginfo_t *ksi)
break;
}
}
} else /* Catch the brace below if we're defined */
#endif /* KERN_SA */
{
LIST_FOREACH(l, &p->p_lwps, l_sibling)
if (sigpost(l, action, prop, kp->ksi_signo, 0) && !toall)
break;
/* Delivered, skip next. */
goto out;
}
out:
/*
* If the ksiginfo wasn't used, then bin it. XXXSMP freeing memory
* with locks held. The caller should take care of this.
*/
ksiginfo_free(kp);
#endif
LIST_FOREACH(l, &p->p_lwps, l_sibling) {
if (sigpost(l, action, prop, kp->ksi_signo, 0) && !toall)
break;
}
out:
/*
* If the ksiginfo wasn't used, then bin it. XXXSMP freeing memory
* with locks held. The caller should take care of this.
*/
ksiginfo_free(kp);
}
void
@ -1878,9 +1871,9 @@ issignal(struct lwp *l)
* but it's not a big deal.
*/
if (p->p_slflag & PSL_TRACED ||
((p->p_lflag & PL_ORPHANPG) != 0 &&
((p->p_lflag & PL_ORPHANPG) != 0 &&
prop & SA_TTYSTOP)) {
/* Ignore the signal. */
/* Ignore the signal. */
continue;
}
/* Take the signal. */
@ -2339,8 +2332,8 @@ proc_unstop(struct proc *p)
continue;
}
if (sig && (l->l_flag & LW_SINTR) != 0) {
setrunnable(l);
sig = 0;
setrunnable(l);
sig = 0;
} else {
l->l_stat = LSSLEEP;
p->p_nrlwps++;
@ -2355,13 +2348,13 @@ filt_sigattach(struct knote *kn)
struct proc *p = curproc;
kn->kn_obj = p;
kn->kn_flags |= EV_CLEAR; /* automatically set */
kn->kn_flags |= EV_CLEAR; /* automatically set */
mutex_enter(p->p_lock);
SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext);
mutex_exit(p->p_lock);
return (0);
return 0;
}
static void
@ -2375,7 +2368,7 @@ filt_sigdetach(struct knote *kn)
}
/*
* signal knotes are shared with proc knotes, so we apply a mask to
* 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.

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_sig.c,v 1.24 2009/12/19 18:25:54 rmind Exp $ */
/* $NetBSD: sys_sig.c,v 1.25 2009/12/20 04:49:09 rmind Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.24 2009/12/19 18:25:54 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.25 2009/12/20 04:49:09 rmind Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -81,9 +81,9 @@ __KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.24 2009/12/19 18:25:54 rmind Exp $");
#include <sys/kmem.h>
#include <sys/module.h>
/* ARGSUSED */
int
sys___sigaction_sigtramp(struct lwp *l, const struct sys___sigaction_sigtramp_args *uap, register_t *retval)
sys___sigaction_sigtramp(struct lwp *l,
const struct sys___sigaction_sigtramp_args *uap, register_t *retval)
{
/* {
syscallarg(int) signum;
@ -110,7 +110,7 @@ sys___sigaction_sigtramp(struct lwp *l, const struct sys___sigaction_sigtramp_ar
if (error)
return (error);
}
return (0);
return 0;
}
/*
@ -118,7 +118,8 @@ sys___sigaction_sigtramp(struct lwp *l, const struct sys___sigaction_sigtramp_ar
* return old mask as return value; the library stub does the rest.
*/
int
sys___sigprocmask14(struct lwp *l, const struct sys___sigprocmask14_args *uap, register_t *retval)
sys___sigprocmask14(struct lwp *l, const struct sys___sigprocmask14_args *uap,
register_t *retval)
{
/* {
syscallarg(int) how;
@ -132,25 +133,25 @@ sys___sigprocmask14(struct lwp *l, const struct sys___sigprocmask14_args *uap, r
if (SCARG(uap, set)) {
error = copyin(SCARG(uap, set), &nss, sizeof(nss));
if (error)
return (error);
return error;
}
mutex_enter(p->p_lock);
error = sigprocmask1(l, SCARG(uap, how),
SCARG(uap, set) ? &nss : 0, SCARG(uap, oset) ? &oss : 0);
mutex_exit(p->p_lock);
if (error)
return (error);
return error;
if (SCARG(uap, oset)) {
error = copyout(&oss, SCARG(uap, oset), sizeof(oss));
if (error)
return (error);
return error;
}
return (0);
return 0;
}
/* ARGSUSED */
int
sys___sigpending14(struct lwp *l, const struct sys___sigpending14_args *uap, register_t *retval)
sys___sigpending14(struct lwp *l, const struct sys___sigpending14_args *uap,
register_t *retval)
{
/* {
syscallarg(sigset_t *) set;
@ -158,7 +159,7 @@ sys___sigpending14(struct lwp *l, const struct sys___sigpending14_args *uap, reg
sigset_t ss;
sigpending1(l, &ss);
return (copyout(&ss, SCARG(uap, set), sizeof(ss)));
return copyout(&ss, SCARG(uap, set), sizeof(ss));
}
/*
@ -166,9 +167,9 @@ sys___sigpending14(struct lwp *l, const struct sys___sigpending14_args *uap, reg
* Note nonstandard calling convention: libc stub passes mask, not pointer,
* to save a copyin.
*/
/* ARGSUSED */
int
sys___sigsuspend14(struct lwp *l, const struct sys___sigsuspend14_args *uap, register_t *retval)
sys___sigsuspend14(struct lwp *l, const struct sys___sigsuspend14_args *uap,
register_t *retval)
{
/* {
syscallarg(const sigset_t *) set;
@ -179,15 +180,14 @@ sys___sigsuspend14(struct lwp *l, const struct sys___sigsuspend14_args *uap, reg
if (SCARG(uap, set)) {
error = copyin(SCARG(uap, set), &ss, sizeof(ss));
if (error)
return (error);
return error;
}
return (sigsuspend1(l, SCARG(uap, set) ? &ss : 0));
return sigsuspend1(l, SCARG(uap, set) ? &ss : 0);
}
/* ARGSUSED */
int
sys___sigaltstack14(struct lwp *l, const struct sys___sigaltstack14_args *uap, register_t *retval)
sys___sigaltstack14(struct lwp *l, const struct sys___sigaltstack14_args *uap,
register_t *retval)
{
/* {
syscallarg(const struct sigaltstack *) nss;
@ -199,21 +199,20 @@ sys___sigaltstack14(struct lwp *l, const struct sys___sigaltstack14_args *uap, r
if (SCARG(uap, nss)) {
error = copyin(SCARG(uap, nss), &nss, sizeof(nss));
if (error)
return (error);
return error;
}
error = sigaltstack1(l,
SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
if (error)
return (error);
return error;
if (SCARG(uap, oss)) {
error = copyout(&oss, SCARG(uap, oss), sizeof(oss));
if (error)
return (error);
return error;
}
return (0);
return 0;
}
/* ARGSUSED */
int
sys_kill(struct lwp *l, const struct sys_kill_args *uap, register_t *retval)
{
@ -227,7 +226,7 @@ sys_kill(struct lwp *l, const struct sys_kill_args *uap, register_t *retval)
int error;
if ((u_int)signum >= NSIG)
return (EINVAL);
return EINVAL;
KSI_INIT(&ksi);
ksi.ksi_signo = signum;
ksi.ksi_code = SI_USER;
@ -238,7 +237,7 @@ sys_kill(struct lwp *l, const struct sys_kill_args *uap, register_t *retval)
mutex_enter(proc_lock);
if ((p = p_find(SCARG(uap, pid), PFIND_LOCKED)) == NULL) {
mutex_exit(proc_lock);
return (ESRCH);
return ESRCH;
}
mutex_enter(p->p_lock);
error = kauth_authorize_process(l->l_cred,
@ -249,22 +248,22 @@ sys_kill(struct lwp *l, const struct sys_kill_args *uap, register_t *retval)
}
mutex_exit(p->p_lock);
mutex_exit(proc_lock);
return (error);
return error;
}
switch (SCARG(uap, pid)) {
case -1: /* broadcast signal */
return (killpg1(l, &ksi, 0, 1));
return killpg1(l, &ksi, 0, 1);
case 0: /* signal own process group */
return (killpg1(l, &ksi, 0, 0));
return killpg1(l, &ksi, 0, 0);
default: /* negative explicit process group */
return (killpg1(l, &ksi, -SCARG(uap, pid), 0));
return killpg1(l, &ksi, -SCARG(uap, pid), 0);
}
/* NOTREACHED */
}
/* ARGSUSED */
int
sys_getcontext(struct lwp *l, const struct sys_getcontext_args *uap, register_t *retval)
sys_getcontext(struct lwp *l, const struct sys_getcontext_args *uap,
register_t *retval)
{
/* {
syscallarg(struct __ucontext *) ucp;
@ -276,12 +275,12 @@ sys_getcontext(struct lwp *l, const struct sys_getcontext_args *uap, register_t
getucontext(l, &uc);
mutex_exit(p->p_lock);
return (copyout(&uc, SCARG(uap, ucp), sizeof (*SCARG(uap, ucp))));
return copyout(&uc, SCARG(uap, ucp), sizeof (*SCARG(uap, ucp)));
}
/* ARGSUSED */
int
sys_setcontext(struct lwp *l, const struct sys_setcontext_args *uap, register_t *retval)
sys_setcontext(struct lwp *l, const struct sys_setcontext_args *uap,
register_t *retval)
{
/* {
syscallarg(const ucontext_t *) ucp;
@ -292,16 +291,16 @@ sys_setcontext(struct lwp *l, const struct sys_setcontext_args *uap, register_t
error = copyin(SCARG(uap, ucp), &uc, sizeof (uc));
if (error)
return (error);
if (!(uc.uc_flags & _UC_CPU))
return (EINVAL);
return error;
if ((uc.uc_flags & _UC_CPU) == 0)
return EINVAL;
mutex_enter(p->p_lock);
error = setucontext(l, &uc);
mutex_exit(p->p_lock);
if (error)
return (error);
return error;
return (EJUSTRETURN);
return EJUSTRETURN;
}
/*
@ -331,7 +330,7 @@ sigaction1(struct lwp *l, int signum, const struct sigaction *nsa,
static bool v0v1valid;
if (signum <= 0 || signum >= NSIG)
return (EINVAL);
return EINVAL;
p = l->l_proc;
error = 0;
@ -494,11 +493,11 @@ sigaction1(struct lwp *l, int signum, const struct sigaction *nsa,
l->l_flag |= LW_PENDSIG;
lwp_unlock(l);
}
out:
out:
mutex_exit(p->p_lock);
ksiginfo_queue_drain(&kq);
return (error);
return error;
}
int
@ -541,7 +540,7 @@ sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss)
}
}
return (0);
return 0;
}
void
@ -558,9 +557,7 @@ sigpending1(struct lwp *l, sigset_t *ss)
int
sigsuspend1(struct lwp *l, const sigset_t *ss)
{
struct proc *p;
p = l->l_proc;
struct proc *p = l->l_proc;
if (ss) {
/*
@ -589,12 +586,12 @@ sigsuspend1(struct lwp *l, const sigset_t *ss)
;
/* always return EINTR rather than ERESTART... */
return (EINTR);
return EINTR;
}
int
sigaltstack1(struct lwp *l, const struct sigaltstack *nss,
struct sigaltstack *oss)
struct sigaltstack *oss)
{
struct proc *p = l->l_proc;
int error = 0;
@ -619,13 +616,12 @@ sigaltstack1(struct lwp *l, const struct sigaltstack *nss,
mutex_exit(p->p_lock);
return (error);
return error;
}
int
__sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap,
register_t *retval,
copyout_t put_info, copyin_t fetch_timeout, copyout_t put_timeout)
register_t *retval, copyout_t storeinf, copyin_t fetchts, copyout_t storets)
{
/* {
syscallarg(const sigset_t *) set;
@ -633,18 +629,15 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap,
syscallarg(struct timespec *) timeout;
} */
struct proc *p = l->l_proc;
int error, signum;
int timo = 0;
int error, signum, timo;
struct timespec ts, tsstart, tsnow;
ksiginfo_t ksi;
memset(&tsstart, 0, sizeof tsstart); /* XXX gcc */
/*
* Calculate timeout, if it was specified.
*/
if (SCARG(uap, timeout)) {
error = (*fetch_timeout)(SCARG(uap, timeout), &ts, sizeof(ts));
error = (*fetchts)(SCARG(uap, timeout), &ts, sizeof(ts));
if (error)
return error;
@ -660,12 +653,15 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap,
* ECANCELED/ERESTART case.
*/
getnanouptime(&tsstart);
} else {
memset(&tsstart, 0, sizeof(tsstart)); /* XXXgcc */
timo = 0;
}
error = copyin(SCARG(uap, set), &l->l_sigwaitset,
sizeof(l->l_sigwaitset));
if (error != 0)
return (error);
if (error)
return error;
/*
* Silently ignore SA_CANTMASK signals. psignal1() would ignore
@ -676,53 +672,46 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap,
mutex_enter(p->p_lock);
/*
* SA processes can have no more than 1 sigwaiter.
*/
/* SA processes can have no more than 1 sigwaiter. */
if ((p->p_sflag & PS_SA) != 0 && !LIST_EMPTY(&p->p_sigwaiters)) {
mutex_exit(p->p_lock);
error = EINVAL;
goto out;
}
/* Check for pending signals in the process, if no - then in LWP. */
if ((signum = sigget(&p->p_sigpend, &ksi, 0, &l->l_sigwaitset)) == 0)
signum = sigget(&l->l_sigpend, &ksi, 0, &l->l_sigwaitset);
if (signum != 0) {
/*
* We found a pending signal - copy it out to the user.
*/
/* If found a pending signal, just copy it out to the user. */
mutex_exit(p->p_lock);
goto out;
}
/*
* Set up the sigwait list.
* Set up the sigwait list and wait for signal to arrive.
* We can either be woken up or time out.
*/
l->l_sigwaited = &ksi;
LIST_INSERT_HEAD(&p->p_sigwaiters, l, l_sigwaiter);
/*
* Wait for signal to arrive. We can either be woken up or time out.
*/
error = cv_timedwait_sig(&l->l_sigcv, p->p_lock, timo);
/*
* Need to find out if we woke as a result of lwp_wakeup() or a
* Need to find out if we woke as a result of _lwp_wakeup() or a
* signal outside our wait set.
*/
if (l->l_sigwaited != NULL) {
if (error == EINTR) {
/* wakeup via _lwp_wakeup() */
/* Wakeup via _lwp_wakeup(). */
error = ECANCELED;
} else if (!error) {
/* spurious wakeup - arrange for syscall restart */
/* Spurious wakeup - arrange for syscall restart. */
error = ERESTART;
}
l->l_sigwaited = NULL;
LIST_REMOVE(l, l_sigwaiter);
}
mutex_exit(p->p_lock);
/*
@ -733,29 +722,29 @@ __sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap,
if (timo && (error == ERESTART || error == ECANCELED)) {
getnanouptime(&tsnow);
/* compute how much time has passed since start */
/* Compute how much time has passed since start. */
timespecsub(&tsnow, &tsstart, &tsnow);
/* substract passed time from timeout */
/* Substract passed time from timeout. */
timespecsub(&ts, &tsnow, &ts);
if (ts.tv_sec < 0)
error = EAGAIN;
else {
/* copy updated timeout to userland */
error = (*put_timeout)(&ts, SCARG(uap, timeout),
/* Copy updated timeout to userland. */
error = (*storets)(&ts, SCARG(uap, timeout),
sizeof(ts));
}
}
out:
/*
* If a signal from the wait set arrived, copy it to userland.
* Copy only the used part of siginfo, the padding part is
* left unchanged (userland is not supposed to touch it anyway).
*/
out:
if (error == 0)
error = (*put_info)(&ksi.ksi_info, SCARG(uap, info),
if (error == 0) {
error = (*storeinf)(&ksi.ksi_info, SCARG(uap, info),
sizeof(ksi.ksi_info));
}
return error;
}