diff options
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r-- | sys/kern/kern_sig.c | 167 |
1 files changed, 81 insertions, 86 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 6e1c1ead1e9..53e72da6b78 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.119 2011/04/03 14:56:28 guenther Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.120 2011/04/15 04:52:40 guenther Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -242,9 +242,9 @@ sys_sigaction(struct proc *p, void *v, register_t *retval) if ((ps->ps_siginfo & bit) != 0) sa->sa_flags |= SA_SIGINFO; if (signum == SIGCHLD) { - if ((p->p_flag & P_NOCLDSTOP) != 0) + if ((ps->ps_flags & SAS_NOCLDSTOP) != 0) sa->sa_flags |= SA_NOCLDSTOP; - if ((p->p_flag & P_NOCLDWAIT) != 0) + if ((ps->ps_flags & SAS_NOCLDWAIT) != 0) sa->sa_flags |= SA_NOCLDWAIT; } if ((sa->sa_mask & bit) == 0) @@ -281,21 +281,22 @@ setsigvec(struct proc *p, int signum, struct sigaction *sa) ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask; if (signum == SIGCHLD) { if (sa->sa_flags & SA_NOCLDSTOP) - atomic_setbits_int(&p->p_flag, P_NOCLDSTOP); + atomic_setbits_int(&ps->ps_flags, SAS_NOCLDSTOP); else - atomic_clearbits_int(&p->p_flag, P_NOCLDSTOP); + atomic_clearbits_int(&ps->ps_flags, SAS_NOCLDSTOP); /* * If the SA_NOCLDWAIT flag is set or the handler * is SIG_IGN we reparent the dying child to PID 1 * (init) which will reap the zombie. Because we use - * init to do our dirty work we never set P_NOCLDWAIT + * init to do our dirty work we never set SAS_NOCLDWAIT * for PID 1. */ - if (p->p_pid != 1 && ((sa->sa_flags & SA_NOCLDWAIT) || + if (initproc->p_sigacts != ps && + ((sa->sa_flags & SA_NOCLDWAIT) || sa->sa_handler == SIG_IGN)) - atomic_setbits_int(&p->p_flag, P_NOCLDWAIT); + atomic_setbits_int(&ps->ps_flags, SAS_NOCLDWAIT); else - atomic_clearbits_int(&p->p_flag, P_NOCLDWAIT); + atomic_clearbits_int(&ps->ps_flags, SAS_NOCLDWAIT); } if ((sa->sa_flags & SA_RESETHAND) != 0) ps->ps_sigreset |= bit; @@ -314,23 +315,23 @@ setsigvec(struct proc *p, int signum, struct sigaction *sa) else ps->ps_sigonstack &= ~bit; /* - * Set bit in p_sigignore for signals that are set to SIG_IGN, + * Set bit in ps_sigignore for signals that are set to SIG_IGN, * and for signals set to SIG_DFL where the default is to ignore. - * However, don't put SIGCONT in p_sigignore, + * However, don't put SIGCONT in ps_sigignore, * as we have to restart the process. */ if (sa->sa_handler == SIG_IGN || (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) { atomic_clearbits_int(&p->p_siglist, bit); if (signum != SIGCONT) - p->p_sigignore |= bit; /* easier in psignal */ - p->p_sigcatch &= ~bit; + ps->ps_sigignore |= bit; /* easier in psignal */ + ps->ps_sigcatch &= ~bit; } else { - p->p_sigignore &= ~bit; + ps->ps_sigignore &= ~bit; if (sa->sa_handler == SIG_DFL) - p->p_sigcatch &= ~bit; + ps->ps_sigcatch &= ~bit; else - p->p_sigcatch |= bit; + ps->ps_sigcatch |= bit; } splx(s); } @@ -342,11 +343,13 @@ setsigvec(struct proc *p, int signum, struct sigaction *sa) void siginit(struct proc *p) { + struct sigacts *ps = p->p_sigacts; int i; for (i = 0; i < NSIG; i++) if (sigprop[i] & SA_IGNORE && i != SIGCONT) - p->p_sigignore |= sigmask(i); + ps->ps_sigignore |= sigmask(i); + ps->ps_flags = SAS_NOCLDWAIT | SAS_NOCLDSTOP; } /* @@ -366,13 +369,13 @@ execsigs(struct proc *p) * through p_sigmask (unless they were caught, * and are now ignored by default). */ - while (p->p_sigcatch) { - nc = ffs((long)p->p_sigcatch); + while (ps->ps_sigcatch) { + nc = ffs((long)ps->ps_sigcatch); mask = sigmask(nc); - p->p_sigcatch &= ~mask; + ps->ps_sigcatch &= ~mask; if (sigprop[nc] & SA_IGNORE) { if (nc != SIGCONT) - p->p_sigignore |= mask; + ps->ps_sigignore |= mask; atomic_clearbits_int(&p->p_siglist, mask); } ps->ps_sigact[nc] = SIG_DFL; @@ -381,11 +384,10 @@ execsigs(struct proc *p) * Reset stack state to the user stack. * Clear set of signals caught on the signal stack. */ - ps->ps_sigstk.ss_flags = SS_DISABLE; - ps->ps_sigstk.ss_size = 0; - ps->ps_sigstk.ss_sp = 0; - ps->ps_flags = 0; - atomic_clearbits_int(&p->p_flag, P_NOCLDWAIT); + p->p_sigstk.ss_flags = SS_DISABLE; + p->p_sigstk.ss_size = 0; + p->p_sigstk.ss_sp = 0; + ps->ps_flags &= ~SAS_NOCLDWAIT; if (ps->ps_sigact[SIGCHLD] == SIG_IGN) ps->ps_sigact[SIGCHLD] = SIG_DFL; } @@ -459,8 +461,8 @@ sys_sigsuspend(struct proc *p, void *v, register_t *retval) * save it here and mark the sigacts structure * to indicate this. */ - ps->ps_oldmask = p->p_sigmask; - ps->ps_flags |= SAS_OLDMASK; + p->p_oldmask = p->p_sigmask; + atomic_setbits_int(&p->p_flag, P_SIGSUSPEND); p->p_sigmask = SCARG(uap, mask) &~ sigcantmask; while (tsleep(ps, PPAUSE|PCATCH, "pause", 0) == 0) /* void */; @@ -476,7 +478,6 @@ sys_osigaltstack(struct proc *p, void *v, register_t *retval) syscallarg(const struct osigaltstack *) nss; syscallarg(struct osigaltstack *) oss; } */ *uap = v; - struct sigacts *psp; struct osigaltstack ss; const struct osigaltstack *nss; struct osigaltstack *oss; @@ -485,13 +486,10 @@ sys_osigaltstack(struct proc *p, void *v, register_t *retval) nss = SCARG(uap, nss); oss = SCARG(uap, oss); - psp = p->p_sigacts; - if ((psp->ps_flags & SAS_ALTSTACK) == 0) - psp->ps_sigstk.ss_flags |= SS_DISABLE; if (oss) { - ss.ss_sp = psp->ps_sigstk.ss_sp; - ss.ss_size = psp->ps_sigstk.ss_size; - ss.ss_flags = psp->ps_sigstk.ss_flags; + ss.ss_sp = p->p_sigstk.ss_sp; + ss.ss_size = p->p_sigstk.ss_size; + ss.ss_flags = p->p_sigstk.ss_flags; if ((error = copyout(&ss, oss, sizeof(ss)))) return (error); } @@ -500,19 +498,19 @@ sys_osigaltstack(struct proc *p, void *v, register_t *retval) error = copyin(nss, &ss, sizeof(ss)); if (error) return (error); + if (p->p_sigstk.ss_flags & SS_ONSTACK) + return (EPERM); + if (ss.ss_flags & ~SS_DISABLE) + return (EINVAL); if (ss.ss_flags & SS_DISABLE) { - if (psp->ps_sigstk.ss_flags & SS_ONSTACK) - return (EINVAL); - psp->ps_flags &= ~SAS_ALTSTACK; - psp->ps_sigstk.ss_flags = ss.ss_flags; + p->p_sigstk.ss_flags = ss.ss_flags; return (0); } if (ss.ss_size < MINSIGSTKSZ) return (ENOMEM); - psp->ps_flags |= SAS_ALTSTACK; - psp->ps_sigstk.ss_sp = ss.ss_sp; - psp->ps_sigstk.ss_size = ss.ss_size; - psp->ps_sigstk.ss_flags = ss.ss_flags; + p->p_sigstk.ss_sp = ss.ss_sp; + p->p_sigstk.ss_size = ss.ss_size; + p->p_sigstk.ss_flags = ss.ss_flags; return (0); } @@ -523,7 +521,6 @@ sys_sigaltstack(struct proc *p, void *v, register_t *retval) syscallarg(const struct sigaltstack *) nss; syscallarg(struct sigaltstack *) oss; } */ *uap = v; - struct sigacts *psp; struct sigaltstack ss; const struct sigaltstack *nss; struct sigaltstack *oss; @@ -532,28 +529,24 @@ sys_sigaltstack(struct proc *p, void *v, register_t *retval) nss = SCARG(uap, nss); oss = SCARG(uap, oss); - psp = p->p_sigacts; - if ((psp->ps_flags & SAS_ALTSTACK) == 0) - psp->ps_sigstk.ss_flags |= SS_DISABLE; - if (oss && (error = copyout(&psp->ps_sigstk, - oss, sizeof(struct sigaltstack)))) + if (oss && (error = copyout(&p->p_sigstk, oss, sizeof(p->p_sigstk)))) return (error); if (nss == NULL) return (0); error = copyin(nss, &ss, sizeof(ss)); if (error) return (error); + if (p->p_sigstk.ss_flags & SS_ONSTACK) + return (EPERM); + if (ss.ss_flags & ~SS_DISABLE) + return (EINVAL); if (ss.ss_flags & SS_DISABLE) { - if (psp->ps_sigstk.ss_flags & SS_ONSTACK) - return (EINVAL); - psp->ps_flags &= ~SAS_ALTSTACK; - psp->ps_sigstk.ss_flags = ss.ss_flags; + p->p_sigstk.ss_flags = ss.ss_flags; return (0); } if (ss.ss_size < MINSIGSTKSZ) return (ENOMEM); - psp->ps_flags |= SAS_ALTSTACK; - psp->ps_sigstk = ss; + p->p_sigstk = ss; return (0); } @@ -737,7 +730,7 @@ trapsignal(struct proc *p, int signum, u_long code, int type, int mask; mask = sigmask(signum); - if ((p->p_flag & P_TRACED) == 0 && (p->p_sigcatch & mask) != 0 && + if ((p->p_flag & P_TRACED) == 0 && (ps->ps_sigcatch & mask) != 0 && (p->p_sigmask & mask) == 0) { #ifdef KTRACE if (KTRPOINT(p, KTR_PSIG)) { @@ -753,16 +746,16 @@ trapsignal(struct proc *p, int signum, u_long code, int type, p->p_sigmask, code, type, sigval); p->p_sigmask |= ps->ps_catchmask[signum]; if ((ps->ps_sigreset & mask) != 0) { - p->p_sigcatch &= ~mask; + ps->ps_sigcatch &= ~mask; if (signum != SIGCONT && sigprop[signum] & SA_IGNORE) - p->p_sigignore |= mask; + ps->ps_sigignore |= mask; ps->ps_sigact[signum] = SIG_DFL; } } else { - ps->ps_sig = signum; - ps->ps_code = code; /* XXX for core dump/debugger */ - ps->ps_type = type; - ps->ps_sigval = sigval; + p->p_sisig = signum; + p->p_sicode = code; /* XXX for core dump/debugger */ + p->p_sitype = type; + p->p_sigval = sigval; ptsignal(p, signum, STHREAD); } } @@ -845,15 +838,15 @@ ptsignal(struct proc *p, int signum, enum signal_type type) /* * If the signal is being ignored, * then we forget about it immediately. - * (Note: we don't set SIGCONT in p_sigignore, + * (Note: we don't set SIGCONT in ps_sigignore, * and if it is set to SIG_IGN, * action will be SIG_DFL here.) */ - if (p->p_sigignore & mask) + if (p->p_sigacts->ps_sigignore & mask) return; if (p->p_sigmask & mask) action = SIG_HOLD; - else if (p->p_sigcatch & mask) + else if (p->p_sigacts->ps_sigcatch & mask) action = SIG_CATCH; else { action = SIG_DFL; @@ -1068,7 +1061,8 @@ issignal(struct proc *p) * We should see pending but ignored signals * only if P_TRACED was on when they were posted. */ - if (mask & p->p_sigignore && (p->p_flag & P_TRACED) == 0) + if (mask & p->p_sigacts->ps_sigignore && + (p->p_flag & P_TRACED) == 0) continue; if (p->p_flag & P_TRACED && @@ -1228,7 +1222,8 @@ proc_stop_sweep(void *v) continue; atomic_clearbits_int(&p->p_flag, P_STOPPED); - if ((p->p_p->ps_pptr->ps_mainproc->p_flag & P_NOCLDSTOP) == 0) + if ((p->p_p->ps_pptr->ps_mainproc->p_sigacts->ps_flags & + SAS_NOCLDSTOP) == 0) prsignal(p->p_p->ps_pptr, SIGCHLD); wakeup(p->p_p->ps_pptr); } @@ -1262,14 +1257,14 @@ postsig(int signum) sigval.sival_ptr = 0; type = SI_USER; - if (ps->ps_sig != signum) { + if (p->p_sisig != signum) { code = 0; type = SI_USER; sigval.sival_ptr = 0; } else { - code = ps->ps_code; - type = ps->ps_type; - sigval = ps->ps_sigval; + code = p->p_sicode; + type = p->p_sitype; + sigval = p->p_sigval; } #ifdef KTRACE @@ -1277,8 +1272,8 @@ postsig(int signum) siginfo_t si; initsiginfo(&si, signum, code, type, sigval); - ktrpsig(p, signum, action, ps->ps_flags & SAS_OLDMASK ? - ps->ps_oldmask : p->p_sigmask, type, &si); + ktrpsig(p, signum, action, p->p_flag & P_SIGSUSPEND ? + p->p_oldmask : p->p_sigmask, type, &si); } #endif if (action == SIG_DFL) { @@ -1310,25 +1305,25 @@ postsig(int signum) #else s = splhigh(); #endif - if (ps->ps_flags & SAS_OLDMASK) { - returnmask = ps->ps_oldmask; - ps->ps_flags &= ~SAS_OLDMASK; + if (p->p_flag & P_SIGSUSPEND) { + atomic_clearbits_int(&p->p_flag, P_SIGSUSPEND); + returnmask = p->p_oldmask; } else returnmask = p->p_sigmask; p->p_sigmask |= ps->ps_catchmask[signum]; if ((ps->ps_sigreset & mask) != 0) { - p->p_sigcatch &= ~mask; + ps->ps_sigcatch &= ~mask; if (signum != SIGCONT && sigprop[signum] & SA_IGNORE) - p->p_sigignore |= mask; + ps->ps_sigignore |= mask; ps->ps_sigact[signum] = SIG_DFL; } splx(s); p->p_stats->p_ru.ru_nsignals++; - if (ps->ps_sig == signum) { - ps->ps_sig = 0; - ps->ps_code = 0; - ps->ps_type = SI_USER; - ps->ps_sigval.sival_ptr = NULL; + if (p->p_sisig == signum) { + p->p_sisig = 0; + p->p_sicode = 0; + p->p_sitype = SI_USER; + p->p_sigval.sival_ptr = NULL; } (*p->p_emul->e_sendsig)(action, signum, returnmask, code, @@ -1354,7 +1349,7 @@ sigexit(struct proc *p, int signum) p->p_acflag |= AXSIG; if (sigprop[signum] & SA_CORE) { - p->p_sigacts->ps_sig = signum; + p->p_sisig = signum; if (coredump(p) == 0) signum |= WCOREFLAG; } @@ -1479,8 +1474,8 @@ coredump_trad(struct proc *p, void *cookie) core.c_midmag = 0; strlcpy(core.c_name, p->p_comm, sizeof(core.c_name)); core.c_nseg = 0; - core.c_signo = p->p_sigacts->ps_sig; - core.c_ucode = p->p_sigacts->ps_code; + core.c_signo = p->p_sisig; + core.c_ucode = p->p_sicode; core.c_cpusize = 0; core.c_tsize = (u_long)ptoa(vm->vm_tsize); core.c_dsize = (u_long)ptoa(vm->vm_dsize); |