1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-14 14:55:41 +00:00

- Replace inline implementations of sigprocmask() with calls to

kern_sigprocmask() in the various binary compatibility emulators.
- Replace calls to sigsuspend(), sigaltstack(), sigaction(), and
  sigprocmask() that used the stackgap with calls to the corresponding
  kern_sig*() functions instead without using the stackgap.
This commit is contained in:
John Baldwin 2003-04-22 18:23:49 +00:00
parent 3301bb2349
commit fe8cdcae87
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113859
8 changed files with 325 additions and 763 deletions

View File

@ -35,6 +35,7 @@
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/unistd.h>
#include <sys/user.h>
@ -303,11 +304,7 @@ linux_rt_sigsuspend(td, uap)
{
int error;
l_sigset_t lmask;
sigset_t *bmask;
struct sigsuspend_args bsd;
caddr_t sg;
sg = stackgap_init();
sigset_t bmask;
#ifdef DEBUG
if (ldebug(rt_sigsuspend))
@ -321,10 +318,8 @@ linux_rt_sigsuspend(td, uap)
if (error)
return (error);
bmask = stackgap_alloc(&sg, sizeof(sigset_t));
linux_to_bsd_sigset(&lmask, bmask);
bsd.sigmask = bmask;
return (sigsuspend(td, &bsd));
linux_to_bsd_sigset(&lmask, &bmask);
return (kern_sigsuspend(td, bmask));
}
int

View File

@ -54,6 +54,7 @@
#include <sys/vmmeter.h>
#include <sys/msgbuf.h>
#include <sys/exec.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/uio.h>
#include <net/netisr.h>
@ -218,49 +219,29 @@ osf1_sigaction(td, uap)
struct thread *td;
struct osf1_sigaction_args *uap;
{
struct osf1_sigaction osa;
struct sigaction nbsa, obsa;
struct sigaction *nbsap;
int error;
caddr_t sg;
struct osf1_sigaction *nosa, *oosa, tmposa;
struct sigaction *nbsa, *obsa, tmpbsa;
struct sigaction_args sa;
sg = stackgap_init();
nosa = uap->nsa;
oosa = uap->osa;
if (osf1_sigdbg && uap->sigtramp)
uprintf("osf1_sigaction: trampoline handler at %p\n",
uap->sigtramp);
td->td_md.osf_sigtramp = uap->sigtramp;
if (oosa != NULL)
obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
else
obsa = NULL;
if (nosa != NULL) {
nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
if ((error = copyin(nosa, &tmposa, sizeof(tmposa))) != 0)
return error;
osf1_to_bsd_sigaction(&tmposa, &tmpbsa);
if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
return error;
td->td_md.osf_sigtramp = uap->sigtramp;
if (uap->nsa != NULL) {
if ((error = copyin(uap->nsa, &osa, sizeof(osa))) != 0)
return (error);
osf1_to_bsd_sigaction(&osa, &nbsa);
nbsap = &nbsa;
} else
nbsa = NULL;
nbsap = NULL;
error = kern_sigaction(td, uap->signum, &nbsa, &obsa, 0);
sa.sig = uap->signum;
sa.act = nbsa;
sa.oact = obsa;
if ((error = sigaction(td, &sa)) != 0)
return error;
if (oosa != NULL) {
if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
return error;
bsd_to_osf1_sigaction(&tmpbsa, &tmposa);
if ((error = copyout(&tmposa, oosa, sizeof(tmposa))) != 0)
return error;
if (error == 0 && uap->osa != NULL) {
bsd_to_osf1_sigaction(&obsa, &osa);
error = copyout(&osa, uap->osa, sizeof(osa));
}
return 0;
return (error);
}
int
@ -268,46 +249,23 @@ osf1_sigaltstack(td, uap)
register struct thread *td;
struct osf1_sigaltstack_args *uap;
{
struct osf1_sigaltstack oss;
struct sigaltstack nbss, obss, *nbssp;
int error;
caddr_t sg;
struct osf1_sigaltstack *noss, *ooss, tmposs;
struct sigaltstack *nbss, *obss, tmpbss;
struct sigaltstack_args sa;
sg = stackgap_init();
noss = uap->nss;
ooss = uap->oss;
if (ooss != NULL)
obss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
else
obss = NULL;
if (noss != NULL) {
nbss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
if ((error = copyin(noss, &tmposs, sizeof(tmposs))) != 0)
return error;
osf1_to_bsd_sigaltstack(&tmposs, &tmpbss);
if ((error = copyout(&tmpbss, nbss, sizeof(tmpbss))) != 0)
return error;
if (uap->nss != NULL) {
if ((error = copyin(uap->nss, &oss, sizeof(oss))) != 0)
return (error);
osf1_to_bsd_sigaltstack(&oss, &nbss);
nbssp = &nbss;
} else
nbss = NULL;
sa.ss = nbss;
sa.oss = obss;
if ((error = sigaltstack(td, &sa)) != 0)
return error;
if (obss != NULL) {
if ((error = copyin(obss, &tmpbss, sizeof(tmpbss))) != 0)
return error;
bsd_to_osf1_sigaltstack(&tmpbss, &tmposs);
if ((error = copyout(&tmposs, ooss, sizeof(tmposs))) != 0)
return error;
nbssp = NULL;
error = kern_sigaltstack(td, nbssp, &obss);
if (error == 0 && uap->oss != NULL) {
bsd_to_osf1_sigaltstack(&obss, &oss);
error = copyout(&oss, uap->oss, sizeof(oss));
}
return 0;
return (error);
}
int
@ -317,10 +275,6 @@ osf1_signal(td, uap)
{
struct proc *p;
int error, signum;
caddr_t sg;
p = td->td_proc;
sg = stackgap_init();
signum = OSF1_SIGNO(uap->signum);
if (signum <= 0 || signum > OSF1_NSIG) {
@ -337,127 +291,81 @@ osf1_signal(td, uap)
* that SIG_HOLD is allowed as
* an action.
*/
if ((u_long)uap->handler == OSF1_SIG_HOLD) {
if ((u_long)uap->handler == OSF1_SIG_HOLD) {
sigset_t mask;
sigset_t *bmask;
struct sigprocmask_args sa;
bmask = stackgap_alloc(&sg, sizeof(sigset_t));
SIGEMPTYSET(mask);
SIGADDSET(mask, signum);
sa.how = SIG_BLOCK;
sa.set = bmask;
sa.oset = NULL;
if ((error = copyout(&mask, bmask, sizeof(mask))) != 0)
return (error);
return sigprocmask(td, &sa);
return (kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
0));
}
/* FALLTHROUGH */
case OSF1_SIGNAL_MASK:
{
struct sigaction_args sa_args;
struct sigaction *nbsa, *obsa, sa;
struct sigaction nbsa, obsa;
nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
sa_args.sig = signum;
sa_args.act = nbsa;
sa_args.oact = obsa;
sa.sa_handler = uap->handler;
SIGEMPTYSET(sa.sa_mask);
sa.sa_flags = 0;
nbsa.sa_handler = uap->handler;
SIGEMPTYSET(nbsa.sa_mask);
nbsa.sa_flags = 0;
#if 0
if (signum != SIGALRM)
sa.sa_flags = SA_RESTART;
nbsa.sa_flags = SA_RESTART;
#endif
if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
return error;
if ((error = sigaction(td, &sa_args)) != 0) {
error = kern_sigaction(td, signum, &nbsa, &obsa, 0);
if (error != 0) {
DPRINTF("signal: sigaction failed: %d\n",
error);
td->td_retval[0] = -1;
return error;
return (error);
}
if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
return error;
td->td_retval[0] = (long)sa.sa_handler;
td->td_retval[0] = (long)obsa.sa_handler;
return 0;
}
case OSF1_SIGHOLD_MASK:
{
struct sigprocmask_args sa;
sigset_t set;
sigset_t *bset;
bset = stackgap_alloc(&sg, sizeof(sigset_t));
SIGEMPTYSET(set);
SIGADDSET(set, signum);
sa.how = SIG_BLOCK;
sa.set = bset;
sa.oset = NULL;
if ((error = copyout(&set, bset, sizeof(set))) != 0)
return (error);
return sigprocmask(td, &sa);
return (kern_sigprocmask(td, SIG_BLOCK, &set, NULL, 0));
}
case OSF1_SIGRELSE_MASK:
{
struct sigprocmask_args sa;
sigset_t set;
sigset_t *bset;
bset = stackgap_alloc(&sg, sizeof(sigset_t));
SIGEMPTYSET(set);
SIGADDSET(set, signum);
sa.how = SIG_UNBLOCK;
sa.set = bset;
sa.oset = NULL;
if ((error = copyout(&set, bset, sizeof(set))) != 0)
return (error);
return sigprocmask(td, &sa);
return (kern_sigprocmask(td, SIG_UNBLOCK, &set, NULL,
0));
}
case OSF1_SIGIGNORE_MASK:
{
struct sigaction_args sa_args;
struct sigaction *bsa, sa;
bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
sa_args.sig = signum;
sa_args.act = bsa;
sa_args.oact = NULL;
struct sigaction sa;
sa.sa_handler = SIG_IGN;
SIGEMPTYSET(sa.sa_mask);
sa.sa_flags = 0;
if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
return error;
if ((error = sigaction(td, &sa_args)) != 0) {
error = kern_sigaction(td, signum, &sa, NULL, 0);
if (error != 0)
DPRINTF(("sigignore: sigaction failed\n"));
return error;
}
return 0;
return (error);
}
case OSF1_SIGPAUSE_MASK:
{
struct sigsuspend_args sa;
sigset_t set;
sigset_t *bmask;
sigset_t mask;
bmask = stackgap_alloc(&sg, sizeof(sigset_t));
p = td->td_proc;
PROC_LOCK(p);
set = td->td_sigmask;
mask = td->td_sigmask;
PROC_UNLOCK(p);
SIGDELSET(set, signum);
sa.sigmask = bmask;
if ((error = copyout(&set, bmask, sizeof(set))) != 0)
return (error);
return sigsuspend(td, &sa);
SIGDELSET(mask, signum);
return kern_sigsuspend(td, mask);
}
default:
@ -473,46 +381,18 @@ osf1_sigprocmask(td, uap)
syscallarg(osf1_sigset_t *) set;
} */ *uap;
{
struct proc *p;
int error;
osf1_sigset_t oss;
sigset_t bss;
sigset_t obss, nbss;
int error;
p = td->td_proc;
error = 0;
/* Fix the return value first if needed */
bsd_to_osf1_sigset(&td->td_sigmask, &oss);
td->td_retval[0] = oss;
osf1_to_bsd_sigset(&uap->mask, &bss);
PROC_LOCK(p);
switch (uap->how) {
case OSF1_SIG_BLOCK:
SIGSETOR(td->td_sigmask, bss);
SIG_CANTMASK(td->td_sigmask);
break;
case OSF1_SIG_UNBLOCK:
SIGSETNAND(td->td_sigmask, bss);
signotify(td);
break;
case OSF1_SIG_SETMASK:
td->td_sigmask = bss;
SIG_CANTMASK(td->td_sigmask);
signotify(td);
break;
default:
error = EINVAL;
break;
/* OSF/1 sigprocmask flag values match FreeBSD flag values. */
osf1_to_bsd_sigset(&uap->mask, &nbss);
error = kern_sigprocmask(td, uap->how, &nbss, &obss, 0);
if (error == 0) {
bsd_to_osf1_sigset(&obss, &oss);
td->td_retval[0] = oss;
}
PROC_UNLOCK(p);
return error;
return (error);
}
int
@ -544,22 +424,12 @@ osf1_sigsuspend(td, uap)
syscallarg(osf1_sigset_t *) ss;
} */ *uap;
{
int error;
caddr_t sg;
osf1_sigset_t oss;
sigset_t bss;
sigset_t *bmask;
struct sigsuspend_args sa;
sg = stackgap_init();
bmask = stackgap_alloc(&sg, sizeof(sigset_t));
oss = uap->ss;
osf1_to_bsd_sigset(&oss, &bss);
sa.sigmask = bmask;
if ((error = copyout(&bss, bmask, sizeof(bss))) != 0)
return (error);
return sigsuspend(td, &sa);
return kern_sigsuspend(td, bss);
}
int

View File

@ -56,6 +56,7 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
@ -358,43 +359,26 @@ struct sigaltstack32 {
int
ia32_sigaltstack(struct thread *td, struct ia32_sigaltstack_args *uap)
{
struct sigaltstack32 s32;
struct sigaltstack ss, oss, *ssp;
int error;
caddr_t sg;
struct sigaltstack32 *p32, *op32, s32;
struct sigaltstack *p = NULL, *op = NULL, s;
p32 = uap->ss;
if (p32) {
sg = stackgap_init();
p = stackgap_alloc(&sg, sizeof(struct sigaltstack));
uap->ss = (struct sigaltstack32 *)p;
error = copyin(p32, &s32, sizeof(s32));
if (uap->ss != NULL) {
error = copyin(uap->ss, &s32, sizeof(s32));
if (error)
return (error);
PTRIN_CP(s32, s, ss_sp);
CP(s32, s, ss_size);
CP(s32, s, ss_flags);
error = copyout(&s, p, sizeof(s));
if (error)
return (error);
}
op32 = uap->oss;
if (op32) {
sg = stackgap_init();
op = stackgap_alloc(&sg, sizeof(struct sigaltstack));
uap->oss = (struct sigaltstack32 *)op;
}
error = sigaltstack(td, (struct sigaltstack_args *) uap);
if (error)
return (error);
if (op32) {
error = copyin(op, &s, sizeof(s));
if (error)
return (error);
PTROUT_CP(s, s32, ss_sp);
CP(s, s32, ss_size);
CP(s, s32, ss_flags);
error = copyout(&s32, op32, sizeof(s32));
PTRIN_CP(s32, ss, ss_sp);
CP(s32, ss, ss_size);
CP(s32, ss, ss_flags);
ssp = &ss;
} else
ssp = NULL;
error = kern_sigaltstack(td, ssp, &oss);
if (error == 0 && uap->oss != NULL) {
PTROUT_CP(oss, s32, ss_sp);
CP(oss, s32, ss_size);
CP(oss, s32, ss_flags);
error = copyout(&s32, uap->oss, sizeof(s32));
}
return (error);
}
@ -1279,43 +1263,26 @@ struct sigaction32 {
int
ia32_sigaction(struct thread *td, struct ia32_sigaction_args *uap)
{
struct sigaction32 s32;
struct sigaction sa, osa, *sap;
int error;
caddr_t sg;
struct sigaction32 *p32, *op32, s32;
struct sigaction *p = NULL, *op = NULL, s;
p32 = uap->act;
if (p32) {
sg = stackgap_init();
p = stackgap_alloc(&sg, sizeof(struct sigaction));
uap->act = (struct sigaction32 *)p;
error = copyin(p32, &s32, sizeof(s32));
if (uap->act) {
error = copyin(uap->act, &s32, sizeof(s32));
if (error)
return (error);
s.sa_handler = PTRIN(s32.sa_u);
CP(s32, s, sa_flags);
CP(s32, s, sa_mask);
error = copyout(&s, p, sizeof(s));
if (error)
return (error);
}
op32 = uap->oact;
if (op32) {
sg = stackgap_init();
op = stackgap_alloc(&sg, sizeof(struct sigaction));
uap->oact = (struct sigaction32 *)op;
}
error = sigaction(td, (struct sigaction_args *) uap);
if (error)
return (error);
if (op32) {
error = copyin(op, &s, sizeof(s));
if (error)
return (error);
s32.sa_u = PTROUT(s.sa_handler);
CP(s, s32, sa_flags);
CP(s, s32, sa_mask);
error = copyout(&s32, op32, sizeof(s32));
sa.sa_handler = PTRIN(s32.sa_u);
CP(s32, sa, sa_flags);
CP(s32, sa, sa_mask);
sap = &sa;
} else
sap = NULL;
error = kern_sigaction(td, uap->sig, sap, &osa, 0);
if (error != 0 && uap->oact != NULL) {
s32.sa_u = PTROUT(osa.sa_handler);
CP(osa, s32, sa_flags);
CP(osa, s32, sa_mask);
error = copyout(&s32, uap->oact, sizeof(s32));
}
return (error);
}

View File

@ -56,6 +56,7 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
@ -358,43 +359,26 @@ struct sigaltstack32 {
int
ia32_sigaltstack(struct thread *td, struct ia32_sigaltstack_args *uap)
{
struct sigaltstack32 s32;
struct sigaltstack ss, oss, *ssp;
int error;
caddr_t sg;
struct sigaltstack32 *p32, *op32, s32;
struct sigaltstack *p = NULL, *op = NULL, s;
p32 = uap->ss;
if (p32) {
sg = stackgap_init();
p = stackgap_alloc(&sg, sizeof(struct sigaltstack));
uap->ss = (struct sigaltstack32 *)p;
error = copyin(p32, &s32, sizeof(s32));
if (uap->ss != NULL) {
error = copyin(uap->ss, &s32, sizeof(s32));
if (error)
return (error);
PTRIN_CP(s32, s, ss_sp);
CP(s32, s, ss_size);
CP(s32, s, ss_flags);
error = copyout(&s, p, sizeof(s));
if (error)
return (error);
}
op32 = uap->oss;
if (op32) {
sg = stackgap_init();
op = stackgap_alloc(&sg, sizeof(struct sigaltstack));
uap->oss = (struct sigaltstack32 *)op;
}
error = sigaltstack(td, (struct sigaltstack_args *) uap);
if (error)
return (error);
if (op32) {
error = copyin(op, &s, sizeof(s));
if (error)
return (error);
PTROUT_CP(s, s32, ss_sp);
CP(s, s32, ss_size);
CP(s, s32, ss_flags);
error = copyout(&s32, op32, sizeof(s32));
PTRIN_CP(s32, ss, ss_sp);
CP(s32, ss, ss_size);
CP(s32, ss, ss_flags);
ssp = &ss;
} else
ssp = NULL;
error = kern_sigaltstack(td, ssp, &oss);
if (error == 0 && uap->oss != NULL) {
PTROUT_CP(oss, s32, ss_sp);
CP(oss, s32, ss_size);
CP(oss, s32, ss_flags);
error = copyout(&s32, uap->oss, sizeof(s32));
}
return (error);
}
@ -1279,43 +1263,26 @@ struct sigaction32 {
int
ia32_sigaction(struct thread *td, struct ia32_sigaction_args *uap)
{
struct sigaction32 s32;
struct sigaction sa, osa, *sap;
int error;
caddr_t sg;
struct sigaction32 *p32, *op32, s32;
struct sigaction *p = NULL, *op = NULL, s;
p32 = uap->act;
if (p32) {
sg = stackgap_init();
p = stackgap_alloc(&sg, sizeof(struct sigaction));
uap->act = (struct sigaction32 *)p;
error = copyin(p32, &s32, sizeof(s32));
if (uap->act) {
error = copyin(uap->act, &s32, sizeof(s32));
if (error)
return (error);
s.sa_handler = PTRIN(s32.sa_u);
CP(s32, s, sa_flags);
CP(s32, s, sa_mask);
error = copyout(&s, p, sizeof(s));
if (error)
return (error);
}
op32 = uap->oact;
if (op32) {
sg = stackgap_init();
op = stackgap_alloc(&sg, sizeof(struct sigaction));
uap->oact = (struct sigaction32 *)op;
}
error = sigaction(td, (struct sigaction_args *) uap);
if (error)
return (error);
if (op32) {
error = copyin(op, &s, sizeof(s));
if (error)
return (error);
s32.sa_u = PTROUT(s.sa_handler);
CP(s, s32, sa_flags);
CP(s, s32, sa_mask);
error = copyout(&s32, op32, sizeof(s32));
sa.sa_handler = PTRIN(s32.sa_u);
CP(s32, sa, sa_flags);
CP(s32, sa, sa_mask);
sap = &sa;
} else
sap = NULL;
error = kern_sigaction(td, uap->sig, sap, &osa, 0);
if (error != 0 && uap->oact != NULL) {
s32.sa_u = PTROUT(osa.sa_handler);
CP(osa, s32, sa_flags);
CP(osa, s32, sa_mask);
error = copyout(&s32, uap->oact, sizeof(s32));
}
return (error);
}

View File

@ -227,40 +227,22 @@ static int
linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new,
l_sigset_t *old)
{
sigset_t omask, nmask;
sigset_t *nmaskp;
int error;
sigset_t mask;
struct proc *p = td->td_proc;
error = 0;
td->td_retval[0] = 0;
PROC_LOCK(p);
if (old != NULL)
bsd_to_linux_sigset(&td->td_sigmask, old);
if (new != NULL) {
linux_to_bsd_sigset(new, &mask);
linux_to_bsd_sigset(new, &nmask);
nmaskp = &nmask;
} else
nmaskp = NULL;
switch (how) {
case LINUX_SIG_BLOCK:
SIGSETOR(td->td_sigmask, mask);
SIG_CANTMASK(td->td_sigmask);
break;
case LINUX_SIG_UNBLOCK:
SIGSETNAND(td->td_sigmask, mask);
signotify(td);
break;
case LINUX_SIG_SETMASK:
td->td_sigmask = mask;
SIG_CANTMASK(td->td_sigmask);
signotify(td);
break;
default:
error = EINVAL;
break;
}
}
PROC_UNLOCK(p);
/* Linux sigprocmask flag values are one less than FreeBSD values. */
error = kern_sigprocmask(td, how + 1, nmaskp, &omask, 0);
if (error != 0 && old != NULL)
bsd_to_linux_sigset(&omask, old);
return (error);
}

View File

@ -36,6 +36,7 @@
#include <sys/proc.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <machine/cpu.h>
@ -262,61 +263,38 @@ svr4_sys_sigaction(td, uap)
register struct thread *td;
struct svr4_sys_sigaction_args *uap;
{
struct svr4_sigaction *nisa, *oisa, tmpisa;
struct sigaction *nbsa, *obsa, tmpbsa;
struct sigaction_args sa;
caddr_t sg;
struct svr4_sigaction isa;
struct sigaction nbsa, obsa;
struct sigaction *nbsap;
int error;
DPRINTF(("@@@ svr4_sys_sigaction(%d, %d, %d)\n", td->td_proc->p_pid,
uap->signum,
SVR4_SVR42BSD_SIG(uap->signum)));
sg = stackgap_init();
nisa = uap->nsa;
oisa = uap->osa;
if (oisa != NULL)
obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
else
obsa = NULL;
if (nisa != NULL) {
nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
return error;
svr4_to_bsd_sigaction(&tmpisa, &tmpbsa);
if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
return error;
if (uap->nsa != NULL) {
if ((error = copyin(uap->nsa, &isa, sizeof(isa))) != 0)
return (error);
svr4_to_bsd_sigaction(&isa, &nbsa);
nbsap = &nbsa;
} else
nbsa = NULL;
nbsap = NULL;
#if defined(DEBUG_SVR4)
{
int i;
for (i = 0; i < 4; i++)
DPRINTF(("\tssa_mask[%d] = %lx\n", i,
nisa->ssa_mask.bits[i]));
DPRINTF(("\tssa_handler = %p\n", nisa->ssa_handler));
isa.ssa_mask.bits[i]));
DPRINTF(("\tssa_handler = %p\n", isa.ssa_handler));
}
#endif
sa.sig = SVR4_SVR42BSD_SIG(uap->signum);
sa.act = nbsa;
sa.oact = obsa;
if ((error = sigaction(td, &sa)) != 0)
return error;
if (oisa != NULL) {
if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
return error;
bsd_to_svr4_sigaction(&tmpbsa, &tmpisa);
if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
return error;
error = kern_sigaction(td, SVR4_SVR42BSD_SIG(uap->signum), nbsap, &obsa,
0);
if (error == 0 && uap->osa != NULL) {
bsd_to_svr4_sigaction(&obsa, &isa);
error = copyout(&isa, uap->osa, sizeof(isa));
}
return 0;
return (error);
}
int
@ -324,47 +302,23 @@ svr4_sys_sigaltstack(td, uap)
register struct thread *td;
struct svr4_sys_sigaltstack_args *uap;
{
struct svr4_sigaltstack *nsss, *osss, tmpsss;
struct sigaltstack *nbss, *obss, tmpbss;
struct sigaltstack_args sa;
caddr_t sg;
int error, *retval;
struct svr4_sigaltstack sss;
struct sigaltstack nbss, obss, *nbssp;
int error;
retval = td->td_retval;
sg = stackgap_init();
nsss = uap->nss;
osss = uap->oss;
if (osss != NULL)
obss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
else
obss = NULL;
if (nsss != NULL) {
nbss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
if ((error = copyin(nsss, &tmpsss, sizeof(tmpsss))) != 0)
return error;
svr4_to_bsd_sigaltstack(&tmpsss, &tmpbss);
if ((error = copyout(&tmpbss, nbss, sizeof(tmpbss))) != 0)
return error;
if (uap->nss != NULL) {
if ((error = copyin(uap->nss, &sss, sizeof(sss))) != 0)
return (error);
svr4_to_bsd_sigaltstack(&sss, &nbss);
nbssp = &nbss;
} else
nbss = NULL;
sa.ss = nbss;
sa.oss = obss;
if ((error = sigaltstack(td, &sa)) != 0)
return error;
if (obss != NULL) {
if ((error = copyin(obss, &tmpbss, sizeof(tmpbss))) != 0)
return error;
bsd_to_svr4_sigaltstack(&tmpbss, &tmpsss);
if ((error = copyout(&tmpsss, osss, sizeof(tmpsss))) != 0)
return error;
nbssp = NULL;
error = kern_sigaltstack(td, nbssp, &obss);
if (error == 0 && uap->oss != NULL) {
bsd_to_svr4_sigaltstack(&obss, &sss);
error = copyout(&sss, uap->oss, sizeof(sss));
}
return 0;
return (error);
}
/*
@ -375,11 +329,12 @@ svr4_sys_signal(td, uap)
register struct thread *td;
struct svr4_sys_signal_args *uap;
{
struct proc *p;
int signum;
int error, *retval = td->td_retval;
caddr_t sg = stackgap_init();
int error;
DPRINTF(("@@@ svr4_sys_signal(%d)\n", td->td_proc->p_pid));
p = td->td_proc;
DPRINTF(("@@@ svr4_sys_signal(%d)\n", p->p_pid));
signum = SVR4_SVR42BSD_SIG(SVR4_SIGNO(uap->signum));
if (signum <= 0 || signum > SVR4_NSIG)
@ -393,99 +348,66 @@ svr4_sys_signal(td, uap)
case SVR4_SIGNAL_MASK:
{
struct sigaction_args sa_args;
struct sigaction *nbsa, *obsa, sa;
nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
sa_args.sig = signum;
sa_args.act = nbsa;
sa_args.oact = obsa;
sa.sa_handler = (sig_t) uap->handler;
SIGEMPTYSET(sa.sa_mask);
sa.sa_flags = 0;
struct sigaction nbsa, obsa;
nbsa.sa_handler = (sig_t) uap->handler;
SIGEMPTYSET(nbsa.sa_mask);
nbsa.sa_flags = 0;
if (signum != SIGALRM)
sa.sa_flags = SA_RESTART;
if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
return error;
if ((error = sigaction(td, &sa_args)) != 0) {
nbsa.sa_flags = SA_RESTART;
error = kern_sigaction(td, signum, &nbsa, &obsa, 0);
if (error != 0) {
DPRINTF(("signal: sigaction failed: %d\n",
error));
*retval = (int)SVR4_SIG_ERR;
return error;
td->td_retval[0] = (int)SVR4_SIG_ERR;
return (error);
}
if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
return error;
*retval = (int)sa.sa_handler;
return 0;
td->td_retval[0] = (int)obsa.sa_handler;
return (0);
}
case SVR4_SIGHOLD_MASK:
sighold:
{
struct sigprocmask_args sa;
sigset_t *set;
sigset_t set;
set = stackgap_alloc(&sg, sizeof(sigset_t));
SIGEMPTYSET(*set);
SIGADDSET(*set, signum);
sa.how = SIG_BLOCK;
sa.set = set;
sa.oset = NULL;
return sigprocmask(td, &sa);
SIGEMPTYSET(set);
SIGADDSET(set, signum);
return (kern_sigprocmask(td, SIG_BLOCK, &set, NULL, 0));
}
case SVR4_SIGRELSE_MASK:
{
struct sigprocmask_args sa;
sigset_t *set;
sigset_t set;
set = stackgap_alloc(&sg, sizeof(sigset_t));
SIGEMPTYSET(*set);
SIGADDSET(*set, signum);
sa.how = SIG_UNBLOCK;
sa.set = set;
sa.oset = NULL;
return sigprocmask(td, &sa);
SIGEMPTYSET(set);
SIGADDSET(set, signum);
return (kern_sigprocmask(td, SIG_UNBLOCK, &set, NULL,
0));
}
case SVR4_SIGIGNORE_MASK:
{
struct sigaction_args sa_args;
struct sigaction *bsa, sa;
bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
sa_args.sig = signum;
sa_args.act = bsa;
sa_args.oact = NULL;
struct sigaction sa;
sa.sa_handler = SIG_IGN;
SIGEMPTYSET(sa.sa_mask);
sa.sa_flags = 0;
if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
return error;
if ((error = sigaction(td, &sa_args)) != 0) {
error = kern_sigaction(td, signum, &sa, NULL, 0);
if (error != 0)
DPRINTF(("sigignore: sigaction failed\n"));
return error;
}
return 0;
return (error);
}
case SVR4_SIGPAUSE_MASK:
{
struct sigsuspend_args sa;
sigset_t *set;
sigset_t mask;
set = stackgap_alloc(&sg, sizeof(sigset_t));
PROC_LOCK(td->td_proc);
*set = td->td_sigmask;
PROC_UNLOCK(td->td_proc);
SIGDELSET(*set, signum);
sa.sigmask = set;
return sigsuspend(td, &sa);
PROC_LOCK(p);
mask = td->td_sigmask;
PROC_UNLOCK(p);
SIGDELSET(mask, signum);
return kern_sigsuspend(td, mask);
}
default:
@ -500,53 +422,25 @@ svr4_sys_sigprocmask(td, uap)
struct svr4_sys_sigprocmask_args *uap;
{
svr4_sigset_t sss;
sigset_t bss;
int error = 0, *retval;
sigset_t oss, nss;
sigset_t *nssp;
int error;
retval = td->td_retval;
if (uap->oset != NULL) {
/* Fix the return value first if needed */
PROC_LOCK(td->td_proc);
bsd_to_svr4_sigset(&td->td_sigmask, &sss);
PROC_UNLOCK(td->td_proc);
if ((error = copyout(&sss, uap->oset, sizeof(sss))) != 0)
if (uap->set != NULL) {
if ((error = copyin(uap->set, &sss, sizeof(sss))) != 0)
return error;
svr4_to_bsd_sigset(&sss, &nss);
nssp = &nss;
} else
nssp = NULL;
/* SVR/4 sigprocmask flag values are the same as the FreeBSD values. */
error = kern_sigprocmask(td, uap->how, nssp, &oss, 0);
if (error == 0 && uap->oset != NULL) {
bsd_to_svr4_sigset(&oss, &sss);
error = copyout(&sss, uap->oset, sizeof(sss));
}
if (uap->set == NULL)
/* Just examine */
return 0;
if ((error = copyin(uap->set, &sss, sizeof(sss))) != 0)
return error;
svr4_to_bsd_sigset(&sss, &bss);
PROC_LOCK(td->td_proc);
switch (uap->how) {
case SVR4_SIG_BLOCK:
SIGSETOR(td->td_sigmask, bss);
SIG_CANTMASK(td->td_sigmask);
break;
case SVR4_SIG_UNBLOCK:
SIGSETNAND(td->td_sigmask, bss);
signotify(td);
break;
case SVR4_SIG_SETMASK:
td->td_sigmask = bss;
SIG_CANTMASK(td->td_sigmask);
signotify(td);
break;
default:
error = EINVAL;
break;
}
PROC_UNLOCK(td->td_proc);
return error;
return (error);
}
int
@ -596,19 +490,14 @@ svr4_sys_sigsuspend(td, uap)
struct svr4_sys_sigsuspend_args *uap;
{
svr4_sigset_t sss;
sigset_t *bss;
struct sigsuspend_args sa;
sigset_t bss;
int error;
caddr_t sg = stackgap_init();
if ((error = copyin(uap->ss, &sss, sizeof(sss))) != 0)
return error;
bss = stackgap_alloc(&sg, sizeof(sigset_t));
svr4_to_bsd_sigset(&sss, bss);
sa.sigmask = bss;
return sigsuspend(td, &sa);
svr4_to_bsd_sigset(&sss, &bss);
return kern_sigsuspend(td, bss);
}
@ -631,15 +520,15 @@ svr4_sys_context(td, uap)
struct svr4_sys_context_args *uap;
{
struct svr4_ucontext uc;
int error;
int error, onstack;
switch (uap->func) {
case 0:
PROC_LOCK(td->td_proc);
DPRINTF(("getcontext(%p)\n", uap->uc));
svr4_getcontext(td, &uc, &td->td_sigmask,
sigonstack(cpu_getstack(td)));
PROC_LOCK(td->td_proc);
onstack = sigonstack(cpu_getstack(td));
PROC_UNLOCK(td->td_proc);
svr4_getcontext(td, &uc, &td->td_sigmask, onstack);
return copyout(&uc, uap->uc, sizeof(uc));
case 1:
@ -670,8 +559,10 @@ svr4_sys_pause(td, uap)
register struct thread *td;
struct svr4_sys_pause_args *uap;
{
struct sigsuspend_args bsa;
sigset_t mask;
bsa.sigmask = &td->td_sigmask;
return sigsuspend(td, &bsa);
PROC_LOCK(td->td_proc);
mask = td->td_sigmask;
PROC_UNLOCK(td->td_proc);
return kern_sigsuspend(td, mask);
}

View File

@ -33,6 +33,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/signalvar.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <i386/ibcs2/ibcs2_types.h>
@ -192,47 +193,25 @@ ibcs2_sigaction(td, uap)
register struct thread *td;
struct ibcs2_sigaction_args *uap;
{
struct ibcs2_sigaction *nisa, *oisa, tmpisa;
struct sigaction *nbsa, *obsa, tmpbsa;
struct sigaction_args sa;
caddr_t sg;
int error;
struct ibcs2_sigaction isa;
struct sigaction nbsa, obsa;
struct sigaction *nbsap;
int error;
sg = stackgap_init();
nisa = uap->act;
oisa = uap->oact;
if (oisa != NULL)
obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
else
obsa = NULL;
if (nisa != NULL) {
nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
return error;
ibcs2_to_bsd_sigaction(&tmpisa, &tmpbsa);
if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
return error;
if (uap->act != NULL) {
if ((error = copyin(uap->act, &isa, sizeof(isa))) != 0)
return (error);
ibcs2_to_bsd_sigaction(&isa, &nbsa);
nbsap = &nbsa;
} else
nbsa = NULL;
sa.sig = ibcs2_to_bsd_sig[_SIG_IDX(uap->sig)];
sa.act = nbsa;
sa.oact = obsa;
if ((error = sigaction(td, &sa)) != 0)
return error;
if (oisa != NULL) {
if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
return error;
bsd_to_ibcs2_sigaction(&tmpbsa, &tmpisa);
if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
return error;
nbsap = NULL;
error = kern_sigaction(td, ibcs2_to_bsd_sig[_SIG_IDX(uap->sig)], &nbsa,
&obsa, 0);
if (error == 0 && uap->oact != NULL) {
bsd_to_ibcs2_sigaction(&obsa, &isa);
error = copyout(&isa, uap->oact, sizeof(isa));
}
return 0;
return (error);
}
int
@ -244,7 +223,6 @@ ibcs2_sigsys(td, uap)
struct sigaction sa;
int signum = ibcs2_to_bsd_sig[_SIG_IDX(IBCS2_SIGNO(uap->sig))];
int error;
caddr_t sg = stackgap_init();
if (signum <= 0 || signum >= IBCS2_NSIG) {
if (IBCS2_SIGCALL(uap->sig) == IBCS2_SIGNAL_MASK ||
@ -269,20 +247,16 @@ ibcs2_sigsys(td, uap)
case IBCS2_SIGHOLD_MASK:
{
sigset_t mask;
struct sigprocmask_args sa;
SIGEMPTYSET(mask);
SIGADDSET(mask, signum);
sa.how = SIG_BLOCK;
sa.set = &mask;
sa.oset = NULL;
return sigprocmask(td, &sa);
return (kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
0));
}
case IBCS2_SIGNAL_MASK:
{
struct sigaction_args sa_args;
struct sigaction *nbsa, *obsa;
struct sigaction osa;
/* do not automatically block signal */
sa.sa_flags = SA_NODEFER;
@ -294,31 +268,20 @@ ibcs2_sigsys(td, uap)
sa.sa_flags |= SA_RESETHAND;
#endif
ibcs2_sigset:
nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
sa_args.sig = signum;
sa_args.act = nbsa;
sa_args.oact = obsa;
sa.sa_handler = uap->fp;
sigemptyset(&sa.sa_mask);
#if 0
if (signum != SIGALRM)
sa.sa_flags |= SA_RESTART;
#endif
td->td_retval[0] = (int)IBCS2_SIG_ERR; /* init error return */
/* perform native sigaction() */
if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
return error;
if ((error = sigaction(td, &sa_args)) != 0) {
error = kern_sigaction(td, signum, &sa, &osa, 0);
if (error != 0) {
DPRINTF(("signal: sigaction failed: %d\n",
error));
return error;
td->td_retval[0] = (int)IBCS2_SIG_ERR;
return (error);
}
if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
return error;
td->td_retval[0] = (int)sa.sa_handler;
td->td_retval[0] = (int)osa.sa_handler;
/* special sigset() check */
if(IBCS2_SIGCALL(uap->sig) == IBCS2_SIGSET_MASK) {
@ -339,49 +302,33 @@ ibcs2_sigsys(td, uap)
case IBCS2_SIGRELSE_MASK:
{
sigset_t mask;
struct sigprocmask_args sa;
SIGEMPTYSET(mask);
SIGADDSET(mask, signum);
sa.how = SIG_UNBLOCK;
sa.set = &mask;
sa.oset = NULL;
return sigprocmask(td, &sa);
return (kern_sigprocmask(td, SIG_UNBLOCK, &mask, NULL,
0));
}
case IBCS2_SIGIGNORE_MASK:
{
struct sigaction_args sa_args;
struct sigaction *bsa;
bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
sa_args.sig = signum;
sa_args.act = bsa;
sa_args.oact = NULL;
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
return error;
if ((error = sigaction(td, &sa_args)) != 0) {
error = kern_sigaction(td, signum, &sa, NULL, 0);
if (error != 0)
DPRINTF(("sigignore: sigaction failed\n"));
return error;
}
return 0;
return (error);
}
case IBCS2_SIGPAUSE_MASK:
{
sigset_t mask;
struct sigsuspend_args sa;
PROC_LOCK(p);
mask = td->td_sigmask;
PROC_UNLOCK(p);
SIGDELSET(mask, signum);
sa.sigmask = &mask;
return sigsuspend(td, &sa);
return kern_sigsuspend(td, mask);
}
default:
@ -394,56 +341,37 @@ ibcs2_sigprocmask(td, uap)
register struct thread *td;
struct ibcs2_sigprocmask_args *uap;
{
struct proc *p = td->td_proc;
ibcs2_sigset_t iss;
sigset_t bss;
int error = 0;
if (uap->oset != NULL) {
/* Fix the return value first if needed */
PROC_LOCK(p);
bsd_to_ibcs2_sigset(&td->td_sigmask, &iss);
PROC_UNLOCK(p);
if ((error = copyout(&iss, uap->oset, sizeof(iss))) != 0)
return error;
}
if (uap->set == NULL)
/* Just examine */
return 0;
if ((error = copyin(uap->set, &iss, sizeof(iss))) != 0)
return error;
ibcs2_to_bsd_sigset(&iss, &bss);
PROC_LOCK(p);
sigset_t oss, nss;
sigset_t *nssp;
int error, how;
switch (uap->how) {
case IBCS2_SIG_BLOCK:
SIGSETOR(td->td_sigmask, bss);
SIG_CANTMASK(td->td_sigmask);
how = SIG_BLOCK;
break;
case IBCS2_SIG_UNBLOCK:
SIGSETNAND(td->td_sigmask, bss);
signotify(td);
how = SIG_UNBLOCK;
break;
case IBCS2_SIG_SETMASK:
td->td_sigmask = bss;
SIG_CANTMASK(td->td_sigmask);
signotify(td);
how = SIG_SETMASK;
break;
default:
error = EINVAL;
break;
return (EINVAL);
}
PROC_UNLOCK(p);
return error;
if (uap->set != NULL) {
if ((error = copyin(uap->set, &iss, sizeof(iss))) != 0)
return error;
ibcs2_to_bsd_sigset(&iss, &nss);
nssp = &nss;
} else
nssp = NULL;
error = kern_sigprocmask(td, how, nssp, &oss, 0);
if (error == 0 && uap->oset != NULL) {
bsd_to_ibcs2_sigset(&oss, &iss);
error = copyout(&iss, uap->oset, sizeof(iss));
}
return (error);
}
int
@ -472,15 +400,13 @@ ibcs2_sigsuspend(td, uap)
{
ibcs2_sigset_t sss;
sigset_t bss;
struct sigsuspend_args sa;
int error;
if ((error = copyin(uap->mask, &sss, sizeof(sss))) != 0)
return error;
ibcs2_to_bsd_sigset(&sss, &bss);
sa.sigmask = &bss;
return sigsuspend(td, &sa);
return kern_sigsuspend(td, bss);
}
int
@ -488,15 +414,12 @@ ibcs2_pause(td, uap)
register struct thread *td;
struct ibcs2_pause_args *uap;
{
struct proc *p = td->td_proc;
sigset_t mask;
struct sigsuspend_args sa;
PROC_LOCK(p);
PROC_LOCK(td->td_proc);
mask = td->td_sigmask;
PROC_UNLOCK(p);
sa.sigmask = &mask;
return sigsuspend(td, &sa);
PROC_UNLOCK(td->td_proc);
return kern_sigsuspend(td, mask);
}
int

View File

@ -56,6 +56,7 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
@ -358,43 +359,26 @@ struct sigaltstack32 {
int
ia32_sigaltstack(struct thread *td, struct ia32_sigaltstack_args *uap)
{
struct sigaltstack32 s32;
struct sigaltstack ss, oss, *ssp;
int error;
caddr_t sg;
struct sigaltstack32 *p32, *op32, s32;
struct sigaltstack *p = NULL, *op = NULL, s;
p32 = uap->ss;
if (p32) {
sg = stackgap_init();
p = stackgap_alloc(&sg, sizeof(struct sigaltstack));
uap->ss = (struct sigaltstack32 *)p;
error = copyin(p32, &s32, sizeof(s32));
if (uap->ss != NULL) {
error = copyin(uap->ss, &s32, sizeof(s32));
if (error)
return (error);
PTRIN_CP(s32, s, ss_sp);
CP(s32, s, ss_size);
CP(s32, s, ss_flags);
error = copyout(&s, p, sizeof(s));
if (error)
return (error);
}
op32 = uap->oss;
if (op32) {
sg = stackgap_init();
op = stackgap_alloc(&sg, sizeof(struct sigaltstack));
uap->oss = (struct sigaltstack32 *)op;
}
error = sigaltstack(td, (struct sigaltstack_args *) uap);
if (error)
return (error);
if (op32) {
error = copyin(op, &s, sizeof(s));
if (error)
return (error);
PTROUT_CP(s, s32, ss_sp);
CP(s, s32, ss_size);
CP(s, s32, ss_flags);
error = copyout(&s32, op32, sizeof(s32));
PTRIN_CP(s32, ss, ss_sp);
CP(s32, ss, ss_size);
CP(s32, ss, ss_flags);
ssp = &ss;
} else
ssp = NULL;
error = kern_sigaltstack(td, ssp, &oss);
if (error == 0 && uap->oss != NULL) {
PTROUT_CP(oss, s32, ss_sp);
CP(oss, s32, ss_size);
CP(oss, s32, ss_flags);
error = copyout(&s32, uap->oss, sizeof(s32));
}
return (error);
}
@ -1279,43 +1263,26 @@ struct sigaction32 {
int
ia32_sigaction(struct thread *td, struct ia32_sigaction_args *uap)
{
struct sigaction32 s32;
struct sigaction sa, osa, *sap;
int error;
caddr_t sg;
struct sigaction32 *p32, *op32, s32;
struct sigaction *p = NULL, *op = NULL, s;
p32 = uap->act;
if (p32) {
sg = stackgap_init();
p = stackgap_alloc(&sg, sizeof(struct sigaction));
uap->act = (struct sigaction32 *)p;
error = copyin(p32, &s32, sizeof(s32));
if (uap->act) {
error = copyin(uap->act, &s32, sizeof(s32));
if (error)
return (error);
s.sa_handler = PTRIN(s32.sa_u);
CP(s32, s, sa_flags);
CP(s32, s, sa_mask);
error = copyout(&s, p, sizeof(s));
if (error)
return (error);
}
op32 = uap->oact;
if (op32) {
sg = stackgap_init();
op = stackgap_alloc(&sg, sizeof(struct sigaction));
uap->oact = (struct sigaction32 *)op;
}
error = sigaction(td, (struct sigaction_args *) uap);
if (error)
return (error);
if (op32) {
error = copyin(op, &s, sizeof(s));
if (error)
return (error);
s32.sa_u = PTROUT(s.sa_handler);
CP(s, s32, sa_flags);
CP(s, s32, sa_mask);
error = copyout(&s32, op32, sizeof(s32));
sa.sa_handler = PTRIN(s32.sa_u);
CP(s32, sa, sa_flags);
CP(s32, sa, sa_mask);
sap = &sa;
} else
sap = NULL;
error = kern_sigaction(td, uap->sig, sap, &osa, 0);
if (error != 0 && uap->oact != NULL) {
s32.sa_u = PTROUT(osa.sa_handler);
CP(osa, s32, sa_flags);
CP(osa, s32, sa_mask);
error = copyout(&s32, uap->oact, sizeof(s32));
}
return (error);
}