diff options
author | luoqi <luoqi@FreeBSD.org> | 1999-10-11 20:33:17 +0000 |
---|---|---|
committer | luoqi <luoqi@FreeBSD.org> | 1999-10-11 20:33:17 +0000 |
commit | fd8b4427a5a052988cfb0778b779cff1a3e09628 (patch) | |
tree | 7cad9d7dad8a4c0a9a157153dada2dbbd270e491 /sys/alpha | |
parent | 031a7ae6a88dcce6c4d95badfd6b19cbe5520d38 (diff) | |
download | FreeBSD-src-fd8b4427a5a052988cfb0778b779cff1a3e09628.zip FreeBSD-src-fd8b4427a5a052988cfb0778b779cff1a3e09628.tar.gz |
Add a per-signal flag to mark handlers registered with osigaction, so we
can provide the correct context to each signal handler.
Fix broken sigsuspend(): don't use p_oldsigmask as a flag, use SAS_OLDMASK
as we did before the linuxthreads support merge (submitted by bde).
Move ps_sigstk from to p_sigacts to the main proc structure since signal
stack should not be shared among threads.
Move SAS_OLDMASK and SAS_ALTSTACK flags from sigacts::ps_flags to proc::p_flag.
Move PS_NOCLDSTOP and PS_NOCLDWAIT flags from proc::p_flag to procsig::ps_flag.
Reviewed by: marcel, jdp, bde
Diffstat (limited to 'sys/alpha')
-rw-r--r-- | sys/alpha/alpha/machdep.c | 56 | ||||
-rw-r--r-- | sys/alpha/linux/linux_sysvec.c | 20 |
2 files changed, 33 insertions, 43 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index ce72dce..38aaee8 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -1172,7 +1172,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) int oonstack, fsize, rndfsize; frame = p->p_md.md_tf; - oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; + oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; fsize = sizeof ksi; rndfsize = ((fsize + 15) / 16) * 16; @@ -1183,11 +1183,11 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) * will fail if the process has not already allocated * the space with a `brk'. */ - if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && + if ((p->p_flag & P_ALTSTACK) && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { - sip = (osiginfo_t *)((caddr_t)psp->ps_sigstk.ss_sp + - psp->ps_sigstk.ss_size - rndfsize); - psp->ps_sigstk.ss_flags |= SS_ONSTACK; + sip = (osiginfo_t *)((caddr_t)p->p_sigstk.ss_sp + + p->p_sigstk.ss_size - rndfsize); + p->p_sigstk.ss_flags |= SS_ONSTACK; } else sip = (osiginfo_t *)(alpha_pal_rdusp() - rndfsize); @@ -1265,29 +1265,26 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) void sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) { - struct proc *p; + struct proc *p = curproc; struct trapframe *frame; - struct sigacts *psp; + struct sigacts *psp = p->p_sigacts; struct sigframe sf, *sfp; - int onstack, rndfsize; + int oonstack, rndfsize; - p = curproc; - - if ((p->p_flag & P_NEWSIGSET) == 0) { + if (SIGISMEMBER(psp->ps_osigset, sig)) { osendsig(catcher, sig, mask, code); return; } frame = p->p_md.md_tf; - psp = p->p_sigacts; - onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0; + oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0; rndfsize = ((sizeof(sf) + 15) / 16) * 16; /* save user context */ bzero(&sf, sizeof(struct sigframe)); sf.sf_uc.uc_sigmask = *mask; - sf.sf_uc.uc_stack = psp->ps_sigstk; - sf.sf_uc.uc_mcontext.mc_onstack = onstack; + sf.sf_uc.uc_stack = p->p_sigstk; + sf.sf_uc.uc_mcontext.mc_onstack = oonstack; fill_regs(p, (struct reg *)sf.sf_uc.uc_mcontext.mc_regs); sf.sf_uc.uc_mcontext.mc_regs[R_SP] = alpha_pal_rdusp(); @@ -1308,11 +1305,11 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) * will fail if the process has not already allocated * the space with a `brk'. */ - if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack && + if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { - sfp = (struct sigframe *)((caddr_t)psp->ps_sigstk.ss_sp + - psp->ps_sigstk.ss_size - rndfsize); - psp->ps_sigstk.ss_flags |= SS_ONSTACK; + sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp + + p->p_sigstk.ss_size - rndfsize); + p->p_sigstk.ss_flags |= SS_ONSTACK; } else sfp = (struct sigframe *)(alpha_pal_rdusp() - rndfsize); @@ -1438,20 +1435,16 @@ osigreturn(struct proc *p, * Restore the user-supplied information */ if (ksc.sc_onstack) - p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; + p->p_sigstk.ss_flags |= SS_ONSTACK; else - p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; + p->p_sigstk.ss_flags &= ~SS_ONSTACK; /* * longjmp is still implemented by calling osigreturn. The new * sigmask is stored in sc_reserved, sc_mask is only used for * backward compatibility. */ - if ((p->p_flag & P_NEWSIGSET) == 0) { - OSIG2SIG(ksc.sc_mask, p->p_sigmask); - } - else - p->p_sigmask = *((sigset_t *)(&ksc.sc_reserved[0])); + SIGSETOLD(p->p_sigmask, ksc.sc_mask); SIG_CANTMASK(p->p_sigmask); set_regs(p, (struct reg *)ksc.sc_regs); @@ -1480,11 +1473,10 @@ sigreturn(struct proc *p, struct pcb *pcb; unsigned long val; - ucp = uap->sigcntxp; - - if ((p->p_flag & P_NEWSIGSET) == 0) - return (osigreturn(p, (struct osigreturn_args *)uap)); + if (((struct osigcontext*)uap->sigcntxp)->sc_regs[R_ZERO] == 0xACEDBADE) + return osigreturn(p, (struct osigreturn_args *)uap); + ucp = uap->sigcntxp; pcb = &p->p_addr->u_pcb; #ifdef DEBUG @@ -1514,9 +1506,9 @@ sigreturn(struct proc *p, alpha_pal_wrusp(uc.uc_mcontext.mc_regs[R_SP]); if (uc.uc_mcontext.mc_onstack & 1) - p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; + p->p_sigstk.ss_flags |= SS_ONSTACK; else - p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; + p->p_sigstk.ss_flags &= ~SS_ONSTACK; p->p_sigmask = uc.uc_sigmask; SIG_CANTMASK(p->p_sigmask); diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c index ecaa359..d282439 100644 --- a/sys/alpha/linux/linux_sysvec.c +++ b/sys/alpha/linux/linux_sysvec.c @@ -198,7 +198,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) int oonstack; regs = p->p_md.md_regs; - oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; + oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; #ifdef DEBUG printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n", @@ -207,11 +207,11 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) /* * Allocate space for the signal handler context. */ - if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && + if ((p->p_flag & P_ALTSTACK) && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { - fp = (struct linux_sigframe *)(psp->ps_sigstk.ss_sp + - psp->ps_sigstk.ss_size - sizeof(struct linux_sigframe)); - psp->ps_sigstk.ss_flags |= SS_ONSTACK; + fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp + + p->p_sigstk.ss_size - sizeof(struct linux_sigframe)); + p->p_sigstk.ss_flags |= SS_ONSTACK; } else { fp = (struct linux_sigframe *)regs->tf_esp - 1; } @@ -287,6 +287,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) regs->tf_ds = _udatasel; regs->tf_es = _udatasel; regs->tf_fs = _udatasel; + load_gs(_udatasel); regs->tf_ss = _udatasel; } @@ -354,12 +355,9 @@ linux_sigreturn(p, args) return(EINVAL); } - p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; - SIGEMPTYSET(p->p_sigmask); - p->p_sigmask.__bits[0] = context.sc_mask; - SIGDELSET(p->p_sigmask, SIGKILL); - SIGDELSET(p->p_sigmask, SIGCONT); - SIGDELSET(p->p_sigmask, SIGSTOP); + p->p_sigstk.ss_flags &= ~SS_ONSTACK; + SIGSETOLD(p->p_sigmask, context.sc_mask); + SIG_CANTMASK(p->p_sigmask); /* * Restore signal context. |