Index: amd64/amd64/machdep.c =================================================================== --- amd64/amd64/machdep.c (revision 274791) +++ amd64/amd64/machdep.c (working copy) @@ -331,7 +331,7 @@ * specified pc, psl. */ void -sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct sigframe sf, *sfp; struct pcb *pcb; @@ -406,7 +406,7 @@ regs->tf_rdi = sig; /* arg 1 in %rdi */ regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */ bzero(&sf.sf_si, sizeof(sf.sf_si)); - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */ sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; Index: amd64/ia32/ia32_signal.c =================================================================== --- amd64/ia32/ia32_signal.c (revision 274791) +++ amd64/ia32/ia32_signal.c (working copy) @@ -82,7 +82,7 @@ #include #ifdef COMPAT_FREEBSD4 -static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *); +static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *, u_int32_t); #endif #define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) @@ -332,7 +332,7 @@ #ifdef COMPAT_43 static void -ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct ia32_sigframe3 sf, *fp; struct proc *p; @@ -367,7 +367,7 @@ /* Build the argument list for the signal handler. */ sf.sf_signum = sig; sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ sf.sf_arg2 = (register_t)&fp->sf_siginfo; sf.sf_siginfo.si_signo = sig; @@ -434,7 +434,7 @@ #ifdef COMPAT_FREEBSD4 static void -freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct ia32_sigframe4 sf, *sfp; struct siginfo32 siginfo; @@ -506,7 +506,7 @@ sf.sf_signum = sig; sf.sf_ucontext = (register_t)&sfp->sf_uc; bzero(&sf.sf_si, sizeof(sf.sf_si)); - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; sf.sf_ah = (u_int32_t)(uintptr_t)catcher; @@ -549,7 +549,7 @@ #endif /* COMPAT_FREEBSD4 */ void -ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct ia32_sigframe sf, *sfp; struct siginfo32 siginfo; @@ -571,13 +571,13 @@ psp = p->p_sigacts; #ifdef COMPAT_FREEBSD4 if (SIGISMEMBER(psp->ps_freebsd4, sig)) { - freebsd4_ia32_sendsig(catcher, ksi, mask); + freebsd4_ia32_sendsig(catcher, ksi, mask, flags); return; } #endif #ifdef COMPAT_43 if (SIGISMEMBER(psp->ps_osigset, sig)) { - ia32_osendsig(catcher, ksi, mask); + ia32_osendsig(catcher, ksi, mask, flags); return; } #endif @@ -651,7 +651,7 @@ sf.sf_signum = sig; sf.sf_ucontext = (register_t)&sfp->sf_uc; bzero(&sf.sf_si, sizeof(sf.sf_si)); - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; sf.sf_ah = (u_int32_t)(uintptr_t)catcher; Index: amd64/linux32/linux32_sysvec.c =================================================================== --- amd64/linux32/linux32_sysvec.c (revision 274791) +++ amd64/linux32/linux32_sysvec.c (working copy) @@ -122,7 +122,8 @@ static int elf_linux_fixup(register_t **stack_base, struct image_params *iparams); static register_t *linux_copyout_strings(struct image_params *imgp); -static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); +static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, + u_int32_t); static void exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack); static void linux32_fixlimit(struct rlimit *rl, int which); @@ -299,7 +300,7 @@ extern unsigned long linux_sznonrtsigcode; static void -linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -327,7 +328,7 @@ * Allocate space for the signal handler context. */ if ((td->td_pflags & TDP_ALTSTACK) && !oonstack && - SIGISMEMBER(psp->ps_sigonstack, sig)) { + (flags & SENDSIG_SIGINFO)) { fp = (struct l_rt_sigframe *)(td->td_sigstk.ss_sp + td->td_sigstk.ss_size - sizeof(struct l_rt_sigframe)); } else Index: compat/ia32/ia32_signal.h =================================================================== --- compat/ia32/ia32_signal.h (revision 274791) +++ compat/ia32/ia32_signal.h (working copy) @@ -200,7 +200,7 @@ extern int sz_freebsd4_ia32_sigcode; extern int sz_ia32_osigcode; extern int sz_lcall_tramp; -void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *); +void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *, u_int32_t); void ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack); int setup_lcall_gate(void); Index: compat/svr4/svr4_signal.h =================================================================== --- compat/svr4/svr4_signal.h (revision 274791) +++ compat/svr4/svr4_signal.h (working copy) @@ -139,6 +139,6 @@ void bsd_to_svr4_sigset(const sigset_t *, svr4_sigset_t *); void svr4_to_bsd_sigaltstack(const struct svr4_sigaltstack *, struct sigaltstack *); void svr4_to_bsd_sigset(const svr4_sigset_t *, sigset_t *); -void svr4_sendsig(sig_t, struct ksiginfo *, sigset_t *); +void svr4_sendsig(sig_t, struct ksiginfo *, sigset_t *, u_int32_t); #endif /* !_SVR4_SIGNAL_H_ */ Index: i386/i386/machdep.c =================================================================== --- i386/i386/machdep.c (revision 274791) +++ i386/i386/machdep.c (working copy) @@ -221,10 +221,10 @@ int cold = 1; #ifdef COMPAT_43 -static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask); +static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask, u_int32_t); #endif #ifdef COMPAT_FREEBSD4 -static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask); +static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask, u_int32_t); #endif long Maxmem = 0; @@ -373,7 +373,7 @@ */ #ifdef COMPAT_43 static void -osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct osigframe sf, *fp; struct proc *p; @@ -411,7 +411,7 @@ sf.sf_signum = sig; sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; bzero(&sf.sf_siginfo, sizeof(sf.sf_siginfo)); - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ sf.sf_arg2 = (register_t)&fp->sf_siginfo; sf.sf_siginfo.si_signo = sig; @@ -509,7 +509,7 @@ #ifdef COMPAT_FREEBSD4 static void -freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct sigframe4 sf, *sfp; struct proc *p; @@ -562,7 +562,7 @@ sf.sf_signum = sig; sf.sf_ucontext = (register_t)&sfp->sf_uc; bzero(&sf.sf_si, sizeof(sf.sf_si)); - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; @@ -635,7 +635,7 @@ #endif /* COMPAT_FREEBSD4 */ void -sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct sigframe sf, *sfp; struct proc *p; @@ -734,7 +734,7 @@ sf.sf_signum = sig; sf.sf_ucontext = (register_t)&sfp->sf_uc; bzero(&sf.sf_si, sizeof(sf.sf_si)); - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; Index: i386/linux/linux_sysvec.c =================================================================== --- i386/linux/linux_sysvec.c (revision 274791) +++ i386/linux/linux_sysvec.c (working copy) @@ -105,7 +105,8 @@ struct image_params *iparams); static int elf_linux_fixup(register_t **stack_base, struct image_params *iparams); -static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); +static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, + u_int32_t); static void exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack); static register_t *linux_copyout_strings(struct image_params *imgp); @@ -537,7 +538,7 @@ * specified pc, psl. */ static void -linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -553,7 +554,7 @@ sig = ksi->ksi_signo; code = ksi->ksi_code; mtx_assert(&psp->ps_mtx, MA_OWNED); - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ linux_rt_sendsig(catcher, ksi, mask); return; Index: i386/svr4/svr4_machdep.c =================================================================== --- i386/svr4/svr4_machdep.c (revision 274791) +++ i386/svr4/svr4_machdep.c (working copy) @@ -410,10 +410,11 @@ * will return to the user pc, psl. */ void -svr4_sendsig(catcher, ksi, mask) +svr4_sendsig(catcher, ksi, mask, flags) sig_t catcher; ksiginfo_t *ksi; sigset_t *mask; + u_int32_t flags; { register struct thread *td = curthread; struct proc *p = td->td_proc; Index: kern/kern_sig.c =================================================================== --- kern/kern_sig.c (revision 274791) +++ kern/kern_sig.c (working copy) @@ -1895,6 +1895,7 @@ struct proc *p; int sig; int code; + u_int32_t ss_flags = 0; p = td->td_proc; sig = ksi->ksi_signo; @@ -1907,6 +1908,8 @@ if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(ps->ps_sigcatch, sig) && !SIGISMEMBER(td->td_sigmask, sig)) { td->td_ru.ru_nsignals++; + if (SIGISMEMBER(ps->ps_siginfo, sig)) + ss_flags |= SENDSIG_SIGINFO; #ifdef KTRACE if (KTRPOINT(curthread, KTR_PSIG)) ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)], @@ -1913,7 +1916,7 @@ &td->td_sigmask, code); #endif (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], - ksi, &td->td_sigmask); + ksi, &td->td_sigmask, ss_flags); mask = ps->ps_catchmask[_SIG_IDX(sig)]; if (!SIGISMEMBER(ps->ps_signodefer, sig)) SIGADDSET(mask, sig); @@ -2803,6 +2806,7 @@ sig_t action; ksiginfo_t ksi; sigset_t returnmask, mask; + u_int32_t ss_flags = 0; KASSERT(sig != 0, ("postsig")); @@ -2843,6 +2847,11 @@ KASSERT(action != SIG_IGN && !SIGISMEMBER(td->td_sigmask, sig), ("postsig action")); /* + * Set SENDSIG_SIGINFO early: sigdflt() may remove it. + */ + if (SIGISMEMBER(ps->ps_siginfo, sig)) + ss_flags |= SENDSIG_SIGINFO; + /* * Set the new mask value and also defer further * occurrences of this signal. * @@ -2870,7 +2879,7 @@ p->p_code = 0; p->p_sig = 0; } - (*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask); + (*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask, ss_flags); } return (1); } Index: mips/mips/freebsd32_machdep.c =================================================================== --- mips/mips/freebsd32_machdep.c (revision 274791) +++ mips/mips/freebsd32_machdep.c (working copy) @@ -69,7 +69,7 @@ static void freebsd32_exec_setregs(struct thread *, struct image_params *, u_long); static int get_mcontext32(struct thread *, mcontext32_t *, int); static int set_mcontext32(struct thread *, const mcontext32_t *); -static void freebsd32_sendsig(sig_t, ksiginfo_t *, sigset_t *); +static void freebsd32_sendsig(sig_t, ksiginfo_t *, sigset_t *, u_int32_t); extern const char *freebsd32_syscallnames[]; @@ -362,7 +362,7 @@ * specified pc, psl. */ static void -freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct proc *p; struct thread *td; @@ -427,7 +427,7 @@ /* Build the argument list for the signal handler. */ td->td_frame->a0 = sig; td->td_frame->a2 = (register_t)(intptr_t)&sfp->sf_uc; - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ td->td_frame->a1 = (register_t)(intptr_t)&sfp->sf_si; /* sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; */ Index: mips/mips/pm_machdep.c =================================================================== --- mips/mips/pm_machdep.c (revision 274791) +++ mips/mips/pm_machdep.c (working copy) @@ -81,7 +81,7 @@ * specified pc, psl. */ void -sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct proc *p; struct thread *td; @@ -142,7 +142,7 @@ /* Build the argument list for the signal handler. */ regs->a0 = sig; regs->a2 = (register_t)(intptr_t)&sfp->sf_uc; - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ regs->a1 = (register_t)(intptr_t)&sfp->sf_si; /* sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; */ Index: powerpc/powerpc/exec_machdep.c =================================================================== --- powerpc/powerpc/exec_machdep.c (revision 274791) +++ powerpc/powerpc/exec_machdep.c (working copy) @@ -122,7 +122,7 @@ static int grab_mcontext(struct thread *, mcontext_t *, int); void -sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct trapframe *tf; struct sigacts *psp; @@ -263,7 +263,7 @@ tf->fixreg[FIRSTARG+2] = (register_t)usfp + offsetof(struct sigframe, sf_uc); #endif - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* * Signal handler installed with SA_SIGINFO. */ Index: sparc64/sparc64/machdep.c =================================================================== --- sparc64/sparc64/machdep.c (revision 274791) +++ sparc64/sparc64/machdep.c (working copy) @@ -596,7 +596,7 @@ } void -sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) +sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask, u_int32_t flags) { struct trapframe *tf; struct sigframe *sfp; @@ -662,7 +662,7 @@ tf->tf_out[0] = sig; tf->tf_out[2] = (register_t)&sfp->sf_uc; tf->tf_out[4] = (register_t)catcher; - if (SIGISMEMBER(psp->ps_siginfo, sig)) { + if (flags & SENDSIG_SIGINFO) { /* Signal handler installed with SA_SIGINFO. */ tf->tf_out[1] = (register_t)&sfp->sf_si; Index: sys/signalvar.h =================================================================== --- sys/signalvar.h (revision 274791) +++ sys/signalvar.h (working copy) @@ -323,6 +323,9 @@ #define SIGPROCMASK_PROC_LOCKED 0x0002 #define SIGPROCMASK_PS_LOCKED 0x0004 +/* Flags for sv_sendsig() */ +#define SENDSIG_SIGINFO 0x00000001 /* Handler is sa_sigaction */ + int cursig(struct thread *td); int sigdeferstop(void); void sigallowstop(void); @@ -337,7 +340,7 @@ int postsig(int sig); void kern_psignal(struct proc *p, int sig); int ptracestop(struct thread *td, int sig); -void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *retmask); +void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *retmask, u_int32_t flags); struct sigacts *sigacts_alloc(void); void sigacts_copy(struct sigacts *dest, struct sigacts *src); void sigacts_free(struct sigacts *ps); Index: sys/sysent.h =================================================================== --- sys/sysent.h (revision 274791) +++ sys/sysent.h (working copy) @@ -100,7 +100,7 @@ /* translate trap-to-signal mapping */ int (*sv_fixup)(register_t **, struct image_params *); /* stack fixup function */ - void (*sv_sendsig)(void (*)(int), struct ksiginfo *, struct __sigset *); + void (*sv_sendsig)(void (*)(int), struct ksiginfo *, struct __sigset *, u_int32_t); /* send signal */ char *sv_sigcode; /* start of sigtramp code */ int *sv_szsigcode; /* size of sigtramp code */