[BACK]Return to kern_sig.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Annotation of src/sys/kern/kern_sig.c, Revision 1.112.2.1

1.112.2.1! nathanw     1: /*     $NetBSD: kern_sig.c,v 1.112 2001/02/26 21:58:30 lukem Exp $     */
1.29      cgd         2:
                      3: /*
                      4:  * Copyright (c) 1982, 1986, 1989, 1991, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  * (c) UNIX System Laboratories, Inc.
                      7:  * All or some portions of this file are derived from material licensed
                      8:  * to the University of California by American Telephone and Telegraph
                      9:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
                     10:  * the permission of UNIX System Laboratories, Inc.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the University of
                     23:  *     California, Berkeley and its contributors.
                     24:  * 4. Neither the name of the University nor the names of its contributors
                     25:  *    may be used to endorse or promote products derived from this software
                     26:  *    without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     29:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     30:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     31:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     32:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     33:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     34:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     35:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     36:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     37:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     38:  * SUCH DAMAGE.
                     39:  *
1.71      fvdl       40:  *     @(#)kern_sig.c  8.14 (Berkeley) 5/14/95
1.29      cgd        41:  */
1.70      mrg        42:
1.73      thorpej    43: #include "opt_ktrace.h"
1.74      thorpej    44: #include "opt_compat_sunos.h"
1.95      eeh        45: #include "opt_compat_netbsd32.h"
1.29      cgd        46:
                     47: #define        SIGPROP         /* include signal properties table */
                     48: #include <sys/param.h>
                     49: #include <sys/signalvar.h>
                     50: #include <sys/resourcevar.h>
                     51: #include <sys/namei.h>
                     52: #include <sys/vnode.h>
1.112.2.1! nathanw    53: #include <sys/lwp.h>
1.29      cgd        54: #include <sys/proc.h>
                     55: #include <sys/systm.h>
                     56: #include <sys/timeb.h>
                     57: #include <sys/times.h>
                     58: #include <sys/buf.h>
                     59: #include <sys/acct.h>
                     60: #include <sys/file.h>
                     61: #include <sys/kernel.h>
                     62: #include <sys/wait.h>
                     63: #include <sys/ktrace.h>
                     64: #include <sys/syslog.h>
                     65: #include <sys/stat.h>
                     66: #include <sys/core.h>
1.53      christos   67: #include <sys/ptrace.h>
1.59      cgd        68: #include <sys/filedesc.h>
1.89      thorpej    69: #include <sys/malloc.h>
                     70: #include <sys/pool.h>
1.112.2.1! nathanw    71: #include <sys/ucontext.h>
1.29      cgd        72:
1.32      cgd        73: #include <sys/mount.h>
                     74: #include <sys/syscallargs.h>
                     75:
1.29      cgd        76: #include <machine/cpu.h>
                     77:
                     78: #include <sys/user.h>          /* for coredump */
1.52      christos   79:
1.69      mrg        80: #include <uvm/uvm_extern.h>
                     81:
1.112     lukem      82: static void    proc_stop(struct proc *p);
                     83: void           killproc(struct proc *, char *);
                     84: static int     build_corename(struct proc *, char [MAXPATHLEN]);
1.95      eeh        85: #if COMPAT_NETBSD32
1.112     lukem      86: static int     coredump32(struct proc *, struct vnode *);
1.95      eeh        87: #endif
1.112     lukem      88: sigset_t       contsigmask, stopsigmask, sigcantmask;
1.29      cgd        89:
1.112     lukem      90: struct pool    sigacts_pool;   /* memory pool for sigacts structures */
1.89      thorpej    91:
1.29      cgd        92: /*
                     93:  * Can process p, with pcred pc, send the signal signum to process q?
                     94:  */
1.112     lukem      95: #define        CANSIGNAL(p, pc, q, signum) \
1.29      cgd        96:        ((pc)->pc_ucred->cr_uid == 0 || \
                     97:            (pc)->p_ruid == (q)->p_cred->p_ruid || \
                     98:            (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
                     99:            (pc)->p_ruid == (q)->p_ucred->cr_uid || \
                    100:            (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
                    101:            ((signum) == SIGCONT && (q)->p_session == (p)->p_session))
                    102:
1.89      thorpej   103: /*
                    104:  * Initialize signal-related data structures.
                    105:  */
                    106: void
1.112     lukem     107: signal_init(void)
1.89      thorpej   108: {
1.112     lukem     109:
1.89      thorpej   110:        pool_init(&sigacts_pool, sizeof(struct sigacts), 0, 0, 0, "sigapl",
                    111:            0, pool_page_alloc_nointr, pool_page_free_nointr, M_SUBPROC);
                    112: }
                    113:
                    114: /*
1.109     jdolecek  115:  * Create an initial sigctx structure, using the same signal state
                    116:  * as p. If 'share' is set, share the sigctx_proc part, otherwise just
                    117:  * copy it from parent.
1.89      thorpej   118:  */
1.109     jdolecek  119: void
1.112     lukem     120: sigactsinit(struct proc *np, struct proc *pp, int share)
1.89      thorpej   121: {
                    122:        struct sigacts *ps;
                    123:
1.109     jdolecek  124:        if (share) {
                    125:                np->p_sigacts = pp->p_sigacts;
                    126:                pp->p_sigacts->sa_refcnt++;
                    127:        } else {
                    128:                ps = pool_get(&sigacts_pool, PR_WAITOK);
                    129:                if (pp)
                    130:                        memcpy(ps, pp->p_sigacts, sizeof(struct sigacts));
                    131:                else
                    132:                        memset(ps, '\0', sizeof(struct sigacts));
                    133:                ps->sa_refcnt = 1;
                    134:                np->p_sigacts = ps;
                    135:        }
1.89      thorpej   136: }
                    137:
                    138: /*
1.109     jdolecek  139:  * Make this process not share its sigctx, maintaining all
1.89      thorpej   140:  * signal state.
                    141:  */
                    142: void
1.112     lukem     143: sigactsunshare(struct proc *p)
1.89      thorpej   144: {
1.109     jdolecek  145:        struct sigacts *oldps;
1.89      thorpej   146:
1.109     jdolecek  147:        if (p->p_sigacts->sa_refcnt == 1)
1.89      thorpej   148:                return;
                    149:
1.109     jdolecek  150:        oldps = p->p_sigacts;
                    151:        sigactsinit(p, NULL, 0);
                    152:
                    153:        if (--oldps->sa_refcnt == 0)
                    154:                pool_put(&sigacts_pool, oldps);
1.89      thorpej   155: }
                    156:
                    157: /*
1.109     jdolecek  158:  * Release a sigctx structure.
1.89      thorpej   159:  */
                    160: void
1.112     lukem     161: sigactsfree(struct proc *p)
1.89      thorpej   162: {
1.112     lukem     163:        struct sigacts *ps;
1.89      thorpej   164:
1.112     lukem     165:        ps = p->p_sigacts;
1.109     jdolecek  166:        if (--ps->sa_refcnt > 0)
1.89      thorpej   167:                return;
                    168:
                    169:        pool_put(&sigacts_pool, ps);
                    170: }
                    171:
1.79      mycroft   172: int
1.112     lukem     173: sigaction1(struct proc *p, int signum, const struct sigaction *nsa,
                    174:        struct sigaction *osa)
1.79      mycroft   175: {
1.112     lukem     176:        struct sigacts  *ps;
                    177:        int             prop;
1.79      mycroft   178:
1.112     lukem     179:        ps = p->p_sigacts;
1.79      mycroft   180:        if (signum <= 0 || signum >= NSIG)
                    181:                return (EINVAL);
                    182:
                    183:        if (osa)
1.109     jdolecek  184:                *osa = SIGACTION_PS(ps, signum);
1.79      mycroft   185:
                    186:        if (nsa) {
                    187:                if (nsa->sa_flags & ~SA_ALLBITS)
                    188:                        return (EINVAL);
                    189:
                    190:                prop = sigprop[signum];
                    191:                if (prop & SA_CANTMASK)
                    192:                        return (EINVAL);
                    193:
1.105     thorpej   194:                (void) splsched();      /* XXXSMP */
1.109     jdolecek  195:                SIGACTION_PS(ps, signum) = *nsa;
                    196:                sigminusset(&sigcantmask, &SIGACTION_PS(ps, signum).sa_mask);
1.79      mycroft   197:                if ((prop & SA_NORESET) != 0)
1.109     jdolecek  198:                        SIGACTION_PS(ps, signum).sa_flags &= ~SA_RESETHAND;
1.79      mycroft   199:                if (signum == SIGCHLD) {
                    200:                        if (nsa->sa_flags & SA_NOCLDSTOP)
                    201:                                p->p_flag |= P_NOCLDSTOP;
                    202:                        else
                    203:                                p->p_flag &= ~P_NOCLDSTOP;
1.82      enami     204:                        if (nsa->sa_flags & SA_NOCLDWAIT) {
1.81      christos  205:                                /*
                    206:                                 * Paranoia: since SA_NOCLDWAIT is implemented
                    207:                                 * by reparenting the dying child to PID 1 (and
1.112     lukem     208:                                 * trust it to reap the zombie), PID 1 itself
                    209:                                 * is forbidden to set SA_NOCLDWAIT.
1.81      christos  210:                                 */
                    211:                                if (p->p_pid == 1)
                    212:                                        p->p_flag &= ~P_NOCLDWAIT;
                    213:                                else
                    214:                                        p->p_flag |= P_NOCLDWAIT;
                    215:                        } else
                    216:                                p->p_flag &= ~P_NOCLDWAIT;
1.79      mycroft   217:                }
                    218:                if ((nsa->sa_flags & SA_NODEFER) == 0)
1.109     jdolecek  219:                        sigaddset(&SIGACTION_PS(ps, signum).sa_mask, signum);
1.79      mycroft   220:                else
1.109     jdolecek  221:                        sigdelset(&SIGACTION_PS(ps, signum).sa_mask, signum);
1.79      mycroft   222:                /*
1.112     lukem     223:                 * Set bit in p_sigctx.ps_sigignore for signals that are set to
                    224:                 * SIG_IGN, and for signals set to SIG_DFL where the default is
                    225:                 * to ignore. However, don't put SIGCONT in
                    226:                 * p_sigctx.ps_sigignore, as we have to restart the process.
                    227:                 */
1.79      mycroft   228:                if (nsa->sa_handler == SIG_IGN ||
                    229:                    (nsa->sa_handler == SIG_DFL && (prop & SA_IGNORE) != 0)) {
1.112     lukem     230:                                                /* never to be seen again */
                    231:                        sigdelset(&p->p_sigctx.ps_siglist, signum);
                    232:                        if (signum != SIGCONT) {
                    233:                                                /* easier in psignal */
                    234:                                sigaddset(&p->p_sigctx.ps_sigignore, signum);
                    235:                        }
1.109     jdolecek  236:                        sigdelset(&p->p_sigctx.ps_sigcatch, signum);
1.79      mycroft   237:                } else {
1.109     jdolecek  238:                        sigdelset(&p->p_sigctx.ps_sigignore, signum);
1.79      mycroft   239:                        if (nsa->sa_handler == SIG_DFL)
1.109     jdolecek  240:                                sigdelset(&p->p_sigctx.ps_sigcatch, signum);
1.79      mycroft   241:                        else
1.109     jdolecek  242:                                sigaddset(&p->p_sigctx.ps_sigcatch, signum);
1.79      mycroft   243:                }
                    244:                (void) spl0();
                    245:        }
                    246:
                    247:        return (0);
                    248: }
                    249:
1.29      cgd       250: /* ARGSUSED */
1.52      christos  251: int
1.112.2.1! nathanw   252: sys___sigaction14(struct lwp *l, void *v, register_t *retval)
1.48      thorpej   253: {
1.98      augustss  254:        struct sys___sigaction14_args /* {
1.112     lukem     255:                syscallarg(int)                         signum;
                    256:                syscallarg(const struct sigaction *)    nsa;
                    257:                syscallarg(struct sigaction *)          osa;
1.48      thorpej   258:        } */ *uap = v;
1.112.2.1! nathanw   259:        struct proc             *p;
1.112     lukem     260:        struct sigaction        nsa, osa;
                    261:        int                     error;
1.29      cgd       262:
1.79      mycroft   263:        if (SCARG(uap, nsa)) {
                    264:                error = copyin(SCARG(uap, nsa), &nsa, sizeof(nsa));
1.52      christos  265:                if (error)
1.29      cgd       266:                        return (error);
                    267:        }
1.112.2.1! nathanw   268:        p = l->l_proc;
1.79      mycroft   269:        error = sigaction1(p, SCARG(uap, signum),
                    270:            SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0);
                    271:        if (error)
                    272:                return (error);
                    273:        if (SCARG(uap, osa)) {
                    274:                error = copyout(&osa, SCARG(uap, osa), sizeof(osa));
1.52      christos  275:                if (error)
1.29      cgd       276:                        return (error);
                    277:        }
                    278:        return (0);
                    279: }
                    280:
                    281: /*
                    282:  * Initialize signal state for process 0;
1.79      mycroft   283:  * set to ignore signals that are ignored by default and disable the signal
                    284:  * stack.
1.29      cgd       285:  */
                    286: void
1.112     lukem     287: siginit(struct proc *p)
1.29      cgd       288: {
1.112     lukem     289:        struct sigacts  *ps;
                    290:        int             signum, prop;
1.79      mycroft   291:
1.112     lukem     292:        ps = p->p_sigacts;
1.79      mycroft   293:        sigemptyset(&contsigmask);
                    294:        sigemptyset(&stopsigmask);
                    295:        sigemptyset(&sigcantmask);
1.85      mycroft   296:        for (signum = 1; signum < NSIG; signum++) {
1.79      mycroft   297:                prop = sigprop[signum];
                    298:                if (prop & SA_CONT)
                    299:                        sigaddset(&contsigmask, signum);
                    300:                if (prop & SA_STOP)
                    301:                        sigaddset(&stopsigmask, signum);
                    302:                if (prop & SA_CANTMASK)
                    303:                        sigaddset(&sigcantmask, signum);
                    304:                if (prop & SA_IGNORE && signum != SIGCONT)
1.109     jdolecek  305:                        sigaddset(&p->p_sigctx.ps_sigignore, signum);
                    306:                sigemptyset(&SIGACTION_PS(ps, signum).sa_mask);
                    307:                SIGACTION_PS(ps, signum).sa_flags = SA_RESTART;
1.79      mycroft   308:        }
1.109     jdolecek  309:        sigemptyset(&p->p_sigctx.ps_sigcatch);
1.79      mycroft   310:        p->p_flag &= ~P_NOCLDSTOP;
1.29      cgd       311:
1.79      mycroft   312:        /*
                    313:         * Reset stack state to the user stack.
                    314:         */
1.109     jdolecek  315:        p->p_sigctx.ps_sigstk.ss_flags = SS_DISABLE;
                    316:        p->p_sigctx.ps_sigstk.ss_size = 0;
                    317:        p->p_sigctx.ps_sigstk.ss_sp = 0;
1.89      thorpej   318:
                    319:        /* One reference. */
1.109     jdolecek  320:        ps->sa_refcnt = 1;
1.29      cgd       321: }
                    322:
                    323: /*
                    324:  * Reset signals for an exec of the specified process.
                    325:  */
                    326: void
1.112     lukem     327: execsigs(struct proc *p)
1.29      cgd       328: {
1.112     lukem     329:        struct sigacts  *ps;
                    330:        int             signum, prop;
1.29      cgd       331:
1.112     lukem     332:        ps = p->p_sigacts;
1.29      cgd       333:        /*
                    334:         * Reset caught signals.  Held signals remain held
1.109     jdolecek  335:         * through p_sigctx.ps_sigmask (unless they were caught,
1.29      cgd       336:         * and are now ignored by default).
                    337:         */
1.85      mycroft   338:        for (signum = 1; signum < NSIG; signum++) {
1.109     jdolecek  339:                if (sigismember(&p->p_sigctx.ps_sigcatch, signum)) {
1.79      mycroft   340:                        prop = sigprop[signum];
                    341:                        if (prop & SA_IGNORE) {
                    342:                                if ((prop & SA_CONT) == 0)
1.112     lukem     343:                                        sigaddset(&p->p_sigctx.ps_sigignore,
                    344:                                            signum);
1.109     jdolecek  345:                                sigdelset(&p->p_sigctx.ps_siglist, signum);
1.79      mycroft   346:                        }
1.109     jdolecek  347:                        SIGACTION_PS(ps, signum).sa_handler = SIG_DFL;
1.29      cgd       348:                }
1.109     jdolecek  349:                sigemptyset(&SIGACTION_PS(ps, signum).sa_mask);
                    350:                SIGACTION_PS(ps, signum).sa_flags = SA_RESTART;
1.29      cgd       351:        }
1.109     jdolecek  352:        sigemptyset(&p->p_sigctx.ps_sigcatch);
1.79      mycroft   353:        p->p_flag &= ~P_NOCLDSTOP;
                    354:
1.29      cgd       355:        /*
                    356:         * Reset stack state to the user stack.
                    357:         */
1.109     jdolecek  358:        p->p_sigctx.ps_sigstk.ss_flags = SS_DISABLE;
                    359:        p->p_sigctx.ps_sigstk.ss_size = 0;
                    360:        p->p_sigctx.ps_sigstk.ss_sp = 0;
1.29      cgd       361: }
                    362:
1.79      mycroft   363: int
1.112     lukem     364: sigprocmask1(struct proc *p, int how, const sigset_t *nss, sigset_t *oss)
1.79      mycroft   365: {
                    366:
                    367:        if (oss)
1.109     jdolecek  368:                *oss = p->p_sigctx.ps_sigmask;
1.79      mycroft   369:
                    370:        if (nss) {
1.105     thorpej   371:                (void)splsched();       /* XXXSMP */
1.79      mycroft   372:                switch (how) {
                    373:                case SIG_BLOCK:
1.109     jdolecek  374:                        sigplusset(nss, &p->p_sigctx.ps_sigmask);
1.79      mycroft   375:                        break;
                    376:                case SIG_UNBLOCK:
1.109     jdolecek  377:                        sigminusset(nss, &p->p_sigctx.ps_sigmask);
1.110     thorpej   378:                        CHECKSIGS(p);
1.79      mycroft   379:                        break;
                    380:                case SIG_SETMASK:
1.109     jdolecek  381:                        p->p_sigctx.ps_sigmask = *nss;
1.110     thorpej   382:                        CHECKSIGS(p);
1.79      mycroft   383:                        break;
                    384:                default:
1.104     thorpej   385:                        (void)spl0();   /* XXXSMP */
1.79      mycroft   386:                        return (EINVAL);
                    387:                }
1.109     jdolecek  388:                sigminusset(&sigcantmask, &p->p_sigctx.ps_sigmask);
1.104     thorpej   389:                (void)spl0();           /* XXXSMP */
1.79      mycroft   390:        }
                    391:
                    392:        return (0);
                    393: }
                    394:
1.29      cgd       395: /*
                    396:  * Manipulate signal mask.
                    397:  * Note that we receive new mask, not pointer,
                    398:  * and return old mask as return value;
                    399:  * the library stub does the rest.
                    400:  */
1.52      christos  401: int
1.112.2.1! nathanw   402: sys___sigprocmask14(struct lwp *l, void *v, register_t *retval)
1.48      thorpej   403: {
1.79      mycroft   404:        struct sys___sigprocmask14_args /* {
1.112     lukem     405:                syscallarg(int)                 how;
                    406:                syscallarg(const sigset_t *)    set;
                    407:                syscallarg(sigset_t *)          oset;
1.48      thorpej   408:        } */ *uap = v;
1.112.2.1! nathanw   409:        struct proc     *p;
1.112     lukem     410:        sigset_t        nss, oss;
                    411:        int             error;
1.29      cgd       412:
1.79      mycroft   413:        if (SCARG(uap, set)) {
                    414:                error = copyin(SCARG(uap, set), &nss, sizeof(nss));
                    415:                if (error)
                    416:                        return (error);
                    417:        }
1.112.2.1! nathanw   418:        p = l->l_proc;
1.79      mycroft   419:        error = sigprocmask1(p, SCARG(uap, how),
                    420:            SCARG(uap, set) ? &nss : 0, SCARG(uap, oset) ? &oss : 0);
                    421:        if (error)
                    422:                return (error);
                    423:        if (SCARG(uap, oset)) {
                    424:                error = copyout(&oss, SCARG(uap, oset), sizeof(oss));
                    425:                if (error)
                    426:                        return (error);
                    427:        }
                    428:        return (0);
                    429: }
                    430:
                    431: void
1.112     lukem     432: sigpending1(struct proc *p, sigset_t *ss)
1.79      mycroft   433: {
1.29      cgd       434:
1.109     jdolecek  435:        *ss = p->p_sigctx.ps_siglist;
                    436:        sigminusset(&p->p_sigctx.ps_sigmask, ss);
1.29      cgd       437: }
                    438:
                    439: /* ARGSUSED */
1.52      christos  440: int
1.112.2.1! nathanw   441: sys___sigpending14(struct lwp *l, void *v, register_t *retval)
1.29      cgd       442: {
1.98      augustss  443:        struct sys___sigpending14_args /* {
1.112     lukem     444:                syscallarg(sigset_t *)  set;
1.79      mycroft   445:        } */ *uap = v;
1.112.2.1! nathanw   446:        struct proc     *p;
        !           447:        sigset_t        ss;
1.79      mycroft   448:
1.112.2.1! nathanw   449:        p = l->l_proc;
1.79      mycroft   450:        sigpending1(p, &ss);
                    451:        return (copyout(&ss, SCARG(uap, set), sizeof(ss)));
                    452: }
                    453:
                    454: int
1.112     lukem     455: sigsuspend1(struct proc *p, const sigset_t *ss)
1.79      mycroft   456: {
1.112     lukem     457:        struct sigacts *ps;
1.29      cgd       458:
1.112     lukem     459:        ps = p->p_sigacts;
1.79      mycroft   460:        if (ss) {
                    461:                /*
                    462:                 * When returning from sigpause, we want
                    463:                 * the old mask to be restored after the
                    464:                 * signal handler has finished.  Thus, we
1.109     jdolecek  465:                 * save it here and mark the sigctx structure
1.79      mycroft   466:                 * to indicate this.
                    467:                 */
1.109     jdolecek  468:                p->p_sigctx.ps_oldmask = p->p_sigctx.ps_sigmask;
                    469:                p->p_sigctx.ps_flags |= SAS_OLDMASK;
1.105     thorpej   470:                (void) splsched();      /* XXXSMP */
1.109     jdolecek  471:                p->p_sigctx.ps_sigmask = *ss;
1.110     thorpej   472:                CHECKSIGS(p);
1.109     jdolecek  473:                sigminusset(&sigcantmask, &p->p_sigctx.ps_sigmask);
1.104     thorpej   474:                (void) spl0();          /* XXXSMP */
1.79      mycroft   475:        }
                    476:
                    477:        while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
                    478:                /* void */;
                    479:        /* always return EINTR rather than ERESTART... */
                    480:        return (EINTR);
1.29      cgd       481: }
                    482:
                    483: /*
                    484:  * Suspend process until signal, providing mask to be set
                    485:  * in the meantime.  Note nonstandard calling convention:
                    486:  * libc stub passes mask, not pointer, to save a copyin.
                    487:  */
                    488: /* ARGSUSED */
                    489: int
1.112.2.1! nathanw   490: sys___sigsuspend14(struct lwp *l, void *v, register_t *retval)
1.48      thorpej   491: {
1.79      mycroft   492:        struct sys___sigsuspend14_args /* {
1.112     lukem     493:                syscallarg(const sigset_t *)    set;
1.48      thorpej   494:        } */ *uap = v;
1.112.2.1! nathanw   495:        struct proc     *p;
1.112     lukem     496:        sigset_t        ss;
                    497:        int             error;
1.79      mycroft   498:
                    499:        if (SCARG(uap, set)) {
                    500:                error = copyin(SCARG(uap, set), &ss, sizeof(ss));
                    501:                if (error)
                    502:                        return (error);
                    503:        }
                    504:
1.112.2.1! nathanw   505:        p = l->l_proc;
1.79      mycroft   506:        return (sigsuspend1(p, SCARG(uap, set) ? &ss : 0));
                    507: }
                    508:
                    509: int
1.112     lukem     510: sigaltstack1(struct proc *p, const struct sigaltstack *nss,
                    511:        struct sigaltstack *oss)
1.79      mycroft   512: {
1.112     lukem     513:
1.79      mycroft   514:        if (oss)
1.109     jdolecek  515:                *oss = p->p_sigctx.ps_sigstk;
1.79      mycroft   516:
                    517:        if (nss) {
                    518:                if (nss->ss_flags & ~SS_ALLBITS)
                    519:                        return (EINVAL);
                    520:
                    521:                if (nss->ss_flags & SS_DISABLE) {
1.109     jdolecek  522:                        if (p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK)
1.79      mycroft   523:                                return (EINVAL);
                    524:                } else {
                    525:                        if (nss->ss_size < MINSIGSTKSZ)
                    526:                                return (ENOMEM);
                    527:                }
1.109     jdolecek  528:                p->p_sigctx.ps_sigstk = *nss;
1.79      mycroft   529:        }
                    530:
                    531:        return (0);
1.29      cgd       532: }
                    533:
                    534: /* ARGSUSED */
1.52      christos  535: int
1.112.2.1! nathanw   536: sys___sigaltstack14(struct lwp *l, void *v, register_t *retval)
1.48      thorpej   537: {
1.98      augustss  538:        struct sys___sigaltstack14_args /* {
1.112     lukem     539:                syscallarg(const struct sigaltstack *)  nss;
                    540:                syscallarg(struct sigaltstack *)        oss;
1.48      thorpej   541:        } */ *uap = v;
1.112.2.1! nathanw   542:        struct proc             *p;
1.112     lukem     543:        struct sigaltstack      nss, oss;
                    544:        int                     error;
1.29      cgd       545:
1.79      mycroft   546:        if (SCARG(uap, nss)) {
                    547:                error = copyin(SCARG(uap, nss), &nss, sizeof(nss));
                    548:                if (error)
                    549:                        return (error);
                    550:        }
1.112.2.1! nathanw   551:        p = l->l_proc;
1.79      mycroft   552:        error = sigaltstack1(p,
                    553:            SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
1.52      christos  554:        if (error)
1.29      cgd       555:                return (error);
1.79      mycroft   556:        if (SCARG(uap, oss)) {
                    557:                error = copyout(&oss, SCARG(uap, oss), sizeof(oss));
                    558:                if (error)
                    559:                        return (error);
1.29      cgd       560:        }
                    561:        return (0);
                    562: }
                    563:
                    564: /* ARGSUSED */
                    565: int
1.112.2.1! nathanw   566: sys_kill(struct lwp *l, void *v, register_t *retval)
1.48      thorpej   567: {
1.98      augustss  568:        struct sys_kill_args /* {
1.112     lukem     569:                syscallarg(int) pid;
                    570:                syscallarg(int) signum;
1.48      thorpej   571:        } */ *uap = v;
1.112.2.1! nathanw   572:        struct proc     *cp, *p;
1.112     lukem     573:        struct pcred    *pc;
1.29      cgd       574:
1.112.2.1! nathanw   575:        cp = l->l_proc;
1.112     lukem     576:        pc = cp->p_cred;
1.32      cgd       577:        if ((u_int)SCARG(uap, signum) >= NSIG)
1.29      cgd       578:                return (EINVAL);
1.32      cgd       579:        if (SCARG(uap, pid) > 0) {
1.29      cgd       580:                /* kill single process */
1.32      cgd       581:                if ((p = pfind(SCARG(uap, pid))) == NULL)
1.29      cgd       582:                        return (ESRCH);
1.32      cgd       583:                if (!CANSIGNAL(cp, pc, p, SCARG(uap, signum)))
1.29      cgd       584:                        return (EPERM);
1.32      cgd       585:                if (SCARG(uap, signum))
                    586:                        psignal(p, SCARG(uap, signum));
1.29      cgd       587:                return (0);
                    588:        }
1.32      cgd       589:        switch (SCARG(uap, pid)) {
1.29      cgd       590:        case -1:                /* broadcast signal */
1.32      cgd       591:                return (killpg1(cp, SCARG(uap, signum), 0, 1));
1.29      cgd       592:        case 0:                 /* signal own process group */
1.32      cgd       593:                return (killpg1(cp, SCARG(uap, signum), 0, 0));
1.29      cgd       594:        default:                /* negative explicit process group */
1.32      cgd       595:                return (killpg1(cp, SCARG(uap, signum), -SCARG(uap, pid), 0));
1.29      cgd       596:        }
                    597:        /* NOTREACHED */
                    598: }
                    599:
                    600: /*
                    601:  * Common code for kill process group/broadcast kill.
                    602:  * cp is calling process.
                    603:  */
1.52      christos  604: int
1.112     lukem     605: killpg1(struct proc *cp, int signum, int pgid, int all)
1.29      cgd       606: {
1.112     lukem     607:        struct proc     *p;
                    608:        struct pcred    *pc;
                    609:        struct pgrp     *pgrp;
                    610:        int             nfound;
1.29      cgd       611:
1.112     lukem     612:        pc = cp->p_cred;
                    613:        nfound = 0;
1.91      thorpej   614:        if (all) {
1.29      cgd       615:                /*
                    616:                 * broadcast
                    617:                 */
1.92      thorpej   618:                proclist_lock_read();
1.31      mycroft   619:                for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
1.29      cgd       620:                        if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
                    621:                            p == cp || !CANSIGNAL(cp, pc, p, signum))
                    622:                                continue;
                    623:                        nfound++;
                    624:                        if (signum)
                    625:                                psignal(p, signum);
                    626:                }
1.91      thorpej   627:                proclist_unlock_read();
                    628:        } else {
1.29      cgd       629:                if (pgid == 0)
                    630:                        /*
                    631:                         * zero pgid means send to my process group.
                    632:                         */
                    633:                        pgrp = cp->p_pgrp;
                    634:                else {
                    635:                        pgrp = pgfind(pgid);
                    636:                        if (pgrp == NULL)
                    637:                                return (ESRCH);
                    638:                }
1.112     lukem     639:                for (p = pgrp->pg_members.lh_first;
                    640:                    p != 0;
                    641:                    p = p->p_pglist.le_next) {
1.29      cgd       642:                        if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
                    643:                            !CANSIGNAL(cp, pc, p, signum))
                    644:                                continue;
                    645:                        nfound++;
1.90      thorpej   646:                        if (signum && P_ZOMBIE(p) == 0)
1.29      cgd       647:                                psignal(p, signum);
                    648:                }
                    649:        }
                    650:        return (nfound ? 0 : ESRCH);
                    651: }
                    652:
                    653: /*
                    654:  * Send a signal to a process group.
                    655:  */
                    656: void
1.112     lukem     657: gsignal(int pgid, int signum)
1.29      cgd       658: {
                    659:        struct pgrp *pgrp;
                    660:
                    661:        if (pgid && (pgrp = pgfind(pgid)))
                    662:                pgsignal(pgrp, signum, 0);
                    663: }
                    664:
                    665: /*
1.71      fvdl      666:  * Send a signal to a process group. If checktty is 1,
1.29      cgd       667:  * limit to members which have a controlling terminal.
                    668:  */
                    669: void
1.112     lukem     670: pgsignal(struct pgrp *pgrp, int signum, int checkctty)
1.29      cgd       671: {
1.98      augustss  672:        struct proc *p;
1.29      cgd       673:
                    674:        if (pgrp)
1.112     lukem     675:                for (p = pgrp->pg_members.lh_first; p != 0;
                    676:                    p = p->p_pglist.le_next)
1.29      cgd       677:                        if (checkctty == 0 || p->p_flag & P_CONTROLT)
                    678:                                psignal(p, signum);
                    679: }
                    680:
                    681: /*
                    682:  * Send a signal caused by a trap to the current process.
                    683:  * If it will be caught immediately, deliver it with correct code.
                    684:  * Otherwise, post it normally.
                    685:  */
                    686: void
1.112.2.1! nathanw   687: trapsignal(struct lwp *l, int signum, u_long code)
1.29      cgd       688: {
1.112.2.1! nathanw   689:        struct proc     *p;
        !           690:        struct sigacts  *ps;
1.29      cgd       691:
1.112.2.1! nathanw   692:        p = l->l_proc;
1.112     lukem     693:        ps = p->p_sigacts;
1.79      mycroft   694:        if ((p->p_flag & P_TRACED) == 0 &&
1.109     jdolecek  695:            sigismember(&p->p_sigctx.ps_sigcatch, signum) &&
                    696:            !sigismember(&p->p_sigctx.ps_sigmask, signum)) {
1.29      cgd       697:                p->p_stats->p_ru.ru_nsignals++;
                    698: #ifdef KTRACE
                    699:                if (KTRPOINT(p, KTR_PSIG))
1.100     sommerfe  700:                        ktrpsig(p, signum,
1.109     jdolecek  701:                            SIGACTION_PS(ps, signum).sa_handler,
                    702:                            &p->p_sigctx.ps_sigmask, code);
1.29      cgd       703: #endif
1.109     jdolecek  704:                (*p->p_emul->e_sendsig)(SIGACTION_PS(ps, signum).sa_handler,
                    705:                    signum, &p->p_sigctx.ps_sigmask, code);
1.105     thorpej   706:                (void) splsched();      /* XXXSMP */
1.112     lukem     707:                sigplusset(&SIGACTION_PS(ps, signum).sa_mask,
                    708:                    &p->p_sigctx.ps_sigmask);
1.109     jdolecek  709:                if (SIGACTION_PS(ps, signum).sa_flags & SA_RESETHAND) {
                    710:                        sigdelset(&p->p_sigctx.ps_sigcatch, signum);
1.45      mycroft   711:                        if (signum != SIGCONT && sigprop[signum] & SA_IGNORE)
1.109     jdolecek  712:                                sigaddset(&p->p_sigctx.ps_sigignore, signum);
                    713:                        SIGACTION_PS(ps, signum).sa_handler = SIG_DFL;
1.45      mycroft   714:                }
1.104     thorpej   715:                (void) spl0();          /* XXXSMP */
1.29      cgd       716:        } else {
1.109     jdolecek  717:                p->p_sigctx.ps_code = code;     /* XXX for core dump/debugger */
                    718:                p->p_sigctx.ps_sig = signum;    /* XXX to verify code */
1.29      cgd       719:                psignal(p, signum);
                    720:        }
                    721: }
                    722:
                    723: /*
                    724:  * Send the signal to the process.  If the signal has an action, the action
                    725:  * is usually performed by the target process rather than the caller; we add
                    726:  * the signal to the set of pending signals for the process.
                    727:  *
                    728:  * Exceptions:
                    729:  *   o When a stop signal is sent to a sleeping process that takes the
                    730:  *     default action, the process is stopped without awakening it.
                    731:  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
                    732:  *     regardless of the signal action (eg, blocked or ignored).
                    733:  *
                    734:  * Other ignored signals are discarded immediately.
1.104     thorpej   735:  *
                    736:  * XXXSMP: Invoked as psignal() or sched_psignal().
1.29      cgd       737:  */
                    738: void
1.112     lukem     739: psignal1(struct proc *p, int signum,
                    740:        int dolock)             /* XXXSMP: works, but icky */
1.29      cgd       741: {
1.112.2.1! nathanw   742:        struct lwp      *l;
        !           743:
        !           744:        int             s, prop;
        !           745:        sig_t           action;
1.29      cgd       746:
1.79      mycroft   747: #ifdef DIAGNOSTIC
                    748:        if (signum <= 0 || signum >= NSIG)
1.29      cgd       749:                panic("psignal signal number");
1.104     thorpej   750:
                    751:        /* XXXSMP: works, but icky */
                    752:        if (dolock)
                    753:                SCHED_ASSERT_UNLOCKED();
                    754:        else
                    755:                SCHED_ASSERT_LOCKED();
1.79      mycroft   756: #endif
1.29      cgd       757:        prop = sigprop[signum];
                    758:
                    759:        /*
                    760:         * If proc is traced, always give parent a chance.
                    761:         */
                    762:        if (p->p_flag & P_TRACED)
                    763:                action = SIG_DFL;
                    764:        else {
                    765:                /*
                    766:                 * If the signal is being ignored,
                    767:                 * then we forget about it immediately.
1.109     jdolecek  768:                 * (Note: we don't set SIGCONT in p_sigctx.ps_sigignore,
1.29      cgd       769:                 * and if it is set to SIG_IGN,
                    770:                 * action will be SIG_DFL here.)
                    771:                 */
1.109     jdolecek  772:                if (sigismember(&p->p_sigctx.ps_sigignore, signum))
1.29      cgd       773:                        return;
1.109     jdolecek  774:                if (sigismember(&p->p_sigctx.ps_sigmask, signum))
1.29      cgd       775:                        action = SIG_HOLD;
1.109     jdolecek  776:                else if (sigismember(&p->p_sigctx.ps_sigcatch, signum))
1.29      cgd       777:                        action = SIG_CATCH;
1.44      mycroft   778:                else {
1.29      cgd       779:                        action = SIG_DFL;
1.44      mycroft   780:
                    781:                        if (prop & SA_KILL && p->p_nice > NZERO)
                    782:                                p->p_nice = NZERO;
                    783:
                    784:                        /*
                    785:                         * If sending a tty stop signal to a member of an
                    786:                         * orphaned process group, discard the signal here if
                    787:                         * the action is default; don't stop the process below
                    788:                         * if sleeping, and don't clear any pending SIGCONT.
                    789:                         */
                    790:                        if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0)
                    791:                                return;
                    792:                }
1.29      cgd       793:        }
                    794:
                    795:        if (prop & SA_CONT)
1.109     jdolecek  796:                sigminusset(&stopsigmask, &p->p_sigctx.ps_siglist);
1.29      cgd       797:
1.44      mycroft   798:        if (prop & SA_STOP)
1.109     jdolecek  799:                sigminusset(&contsigmask, &p->p_sigctx.ps_siglist);
1.44      mycroft   800:
1.109     jdolecek  801:        sigaddset(&p->p_sigctx.ps_siglist, signum);
1.110     thorpej   802:
                    803:        /* CHECKSIGS() is "inlined" here. */
1.109     jdolecek  804:        p->p_sigctx.ps_sigcheck = 1;
1.29      cgd       805:
                    806:        /*
                    807:         * Defer further processing for signals which are held,
                    808:         * except that stopped processes must be continued by SIGCONT.
                    809:         */
                    810:        if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP))
                    811:                return;
1.104     thorpej   812:        /* XXXSMP: works, but icky */
                    813:        if (dolock)
                    814:                SCHED_LOCK(s);
1.112.2.1! nathanw   815:
        !           816:        if (p->p_nrlwps > 0) {
        !           817:                /* An LWP is running. */
        !           818: #ifdef __HAVE_AST_PERPROC
        !           819:                if ((curproc->l_stat == LSONPROC) ||
        !           820:                    (curproc->l_stat == LSRUN) ||
        !           821:                    (curproc->l_stat == LSIDL)) {
        !           822:                        /*
        !           823:                         * LSONPROC: We're running, notice the signal when
        !           824:                         * we return back to userspace.
        !           825:                         *
        !           826:                         * LSRUN, LSIDL: Notice the signal when we run again
        !           827:                         * and return to back to userspace.
        !           828:                         */
        !           829: #else /* ! __HAVE_AST_PERPROC */
        !           830:                if (curproc->l_stat == LSONPROC) { /* XXX SMP */
        !           831:                        /*
        !           832:                         * We're running; notice the signal.
        !           833:                         */
        !           834: #endif /* __HAVE_AST_PERPROC */
        !           835:                        signotify(p);
1.29      cgd       836:                }
1.112.2.1! nathanw   837:                /*
        !           838:                 * The signal will be noticed very soon.
1.29      cgd       839:                 */
1.112.2.1! nathanw   840:                goto out;
        !           841:        } else {
        !           842:                /* Process is sleeping or stopped */
        !           843:                /* Find out if any of the sleeps are interruptable */
        !           844:                for (l = LIST_FIRST(&p->p_lwps);
        !           845:                     l != NULL;
        !           846:                     l = LIST_NEXT(l, l_sibling))
        !           847:                        if (l->l_stat == LSSLEEP &&
        !           848:                            l->l_flag & L_SINTR)
        !           849:                                break;
        !           850:                if (p->p_stat == SACTIVE) {
        !           851:                        /* All LWPs must be sleeping */
        !           852:
        !           853:                        if (l == NULL)
        !           854:                                /* None of them were interruptable */
        !           855:                                goto out;
        !           856:
        !           857:                        if (p->p_flag & P_TRACED)
        !           858:                                goto run;
        !           859:
1.29      cgd       860:                        /*
1.112.2.1! nathanw   861:                         * If SIGCONT is default (or ignored) and process is
        !           862:                         * asleep, we are finished; the process should not
        !           863:                         * be awakened.
1.29      cgd       864:                         */
1.112.2.1! nathanw   865:                        if ((prop & SA_CONT) && action == SIG_DFL) {
        !           866:                                sigdelset(&p->p_sigctx.ps_siglist, signum);
1.29      cgd       867:                                goto out;
1.112.2.1! nathanw   868:                        }
        !           869:
        !           870:                        /*
        !           871:                         * When a sleeping process receives a stop
        !           872:                         * signal, process immediately if possible.
        !           873:                         */
        !           874:                        if ((prop & SA_STOP) && action == SIG_DFL) {
1.104     thorpej   875:                                /*
1.112.2.1! nathanw   876:                                 * If a child holding parent blocked,
        !           877:                                 * stopping could cause deadlock.
1.104     thorpej   878:                                 */
1.112.2.1! nathanw   879:                                if (p->p_flag & P_PPWAIT)
        !           880:                                        goto out;
        !           881:                                sigdelset(&p->p_sigctx.ps_siglist, signum);
        !           882:                                p->p_xstat = signum;
        !           883:                                if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) {
        !           884:                                        /*
        !           885:                                         * XXXSMP: recursive call; don't lock
        !           886:                                         * the second time around.
        !           887:                                         */
        !           888:                                        sched_psignal(p->p_pptr, SIGCHLD);
        !           889:                                }
        !           890:                                proc_stop(p);   /* XXXSMP: recurse? */
        !           891:                                goto out;
1.104     thorpej   892:                        }
1.112.2.1! nathanw   893:                        /*
        !           894:                         * All other (caught or default) signals
        !           895:                         * cause the process to run.
        !           896:                         */
1.29      cgd       897:                        goto runfast;
1.112.2.1! nathanw   898:                        /*NOTREACHED*/
        !           899:                } else if (p->p_stat == SSTOP) {
        !           900:                        /* Process is stopped */
        !           901:                        /*
        !           902:                         * If traced process is already stopped,
        !           903:                         * then no further action is necessary.
        !           904:                         */
        !           905:                        if (p->p_flag & P_TRACED)
        !           906:                                goto out;
1.29      cgd       907:
                    908:                        /*
1.112.2.1! nathanw   909:                         * Kill signal always sets processes running.
1.29      cgd       910:                         */
1.112.2.1! nathanw   911:                        if (signum == SIGKILL)
1.29      cgd       912:                                goto runfast;
1.112.2.1! nathanw   913:
        !           914:                        if (prop & SA_CONT) {
        !           915:                                /*
        !           916:                                 * If SIGCONT is default (or ignored),
        !           917:                                 * we continue the process but don't
        !           918:                                 * leave the signal in ps_siglist, as
        !           919:                                 * it has no further action.  If
        !           920:                                 * SIGCONT is held, we continue the
        !           921:                                 * process and leave the signal in
        !           922:                                 * ps_siglist.  If the process catches
        !           923:                                 * SIGCONT, let it handle the signal
        !           924:                                 * itself.  If it isn't waiting on an
        !           925:                                 * event, then it goes back to run
        !           926:                                 * state.  Otherwise, process goes
        !           927:                                 * back to sleep state.
        !           928:                                 */
        !           929:                                if (action == SIG_DFL)
        !           930:                                        sigdelset(&p->p_sigctx.ps_siglist,
        !           931:                                        signum);
        !           932:                                l = proc_unstop(p);
        !           933:                                if (l && (action == SIG_CATCH))
        !           934:                                        goto runfast;
        !           935:                                if (l)
        !           936:                                        goto run;
        !           937:                                goto out;
        !           938:                        }
        !           939:
        !           940:                        if (prop & SA_STOP) {
        !           941:                                /*
        !           942:                                 * Already stopped, don't need to stop again.
        !           943:                                 * (If we did the shell could get confused.)
        !           944:                                 */
        !           945:                                sigdelset(&p->p_sigctx.ps_siglist, signum);
        !           946:                                goto out;
        !           947:                        }
1.29      cgd       948:
                    949:                        /*
1.112.2.1! nathanw   950:                         * If process is sleeping interruptibly, then
        !           951:                         * simulate a wakeup so that when it is
        !           952:                         * continued, it will be made runnable and can
        !           953:                         * look at the signal.  But don't make the
        !           954:                         * process runnable, leave it stopped.
1.29      cgd       955:                         */
1.112.2.1! nathanw   956:                        if (l)
        !           957:                                unsleep(l);
1.29      cgd       958:                        goto out;
1.112.2.1! nathanw   959:                } else {
        !           960:                        /* Else what? */
        !           961:                        panic("psignal: Invalid process state.");
1.29      cgd       962:                }
                    963:        }
                    964:        /*NOTREACHED*/
                    965:
1.112     lukem     966:  runfast:
1.29      cgd       967:        /*
                    968:         * Raise priority to at least PUSER.
                    969:         */
1.112.2.1! nathanw   970:        if (l->l_priority > PUSER)
        !           971:                l->l_priority = PUSER;
1.112     lukem     972:  run:
1.112.2.1! nathanw   973:        setrunnable(l);         /* XXXSMP: recurse? */
1.112     lukem     974:  out:
1.104     thorpej   975:        /* XXXSMP: works, but icky */
                    976:        if (dolock)
                    977:                SCHED_UNLOCK(s);
1.29      cgd       978: }
                    979:
1.112.2.1! nathanw   980:
1.112     lukem     981: static __inline int firstsig(const sigset_t *);
1.79      mycroft   982:
                    983: static __inline int
1.112     lukem     984: firstsig(const sigset_t *ss)
1.79      mycroft   985: {
                    986:        int sig;
                    987:
                    988:        sig = ffs(ss->__bits[0]);
                    989:        if (sig != 0)
                    990:                return (sig);
                    991: #if NSIG > 33
                    992:        sig = ffs(ss->__bits[1]);
                    993:        if (sig != 0)
                    994:                return (sig + 32);
                    995: #endif
                    996: #if NSIG > 65
                    997:        sig = ffs(ss->__bits[2]);
                    998:        if (sig != 0)
                    999:                return (sig + 64);
                   1000: #endif
                   1001: #if NSIG > 97
                   1002:        sig = ffs(ss->__bits[3]);
                   1003:        if (sig != 0)
                   1004:                return (sig + 96);
                   1005: #endif
                   1006:        return (0);
                   1007: }
                   1008:
1.29      cgd      1009: /*
                   1010:  * If the current process has received a signal (should be caught or cause
                   1011:  * termination, should interrupt current syscall), return the signal number.
                   1012:  * Stop signals with default action are processed immediately, then cleared;
                   1013:  * they aren't returned.  This is checked after each entry to the system for
                   1014:  * a syscall or trap (though this can usually be done without calling issignal
                   1015:  * by checking the pending signal masks in the CURSIG macro.) The normal call
                   1016:  * sequence is
                   1017:  *
                   1018:  *     while (signum = CURSIG(curproc))
                   1019:  *             postsig(signum);
                   1020:  */
                   1021: int
1.112.2.1! nathanw  1022: issignal(struct lwp *l)
1.29      cgd      1023: {
1.112.2.1! nathanw  1024:        struct proc     *p;
1.112     lukem    1025:        int             s, signum, prop;
                   1026:        sigset_t        ss;
1.29      cgd      1027:
1.112.2.1! nathanw  1028:        p = l->l_proc;
1.29      cgd      1029:        for (;;) {
1.79      mycroft  1030:                sigpending1(p, &ss);
1.29      cgd      1031:                if (p->p_flag & P_PPWAIT)
1.79      mycroft  1032:                        sigminusset(&stopsigmask, &ss);
                   1033:                signum = firstsig(&ss);
                   1034:                if (signum == 0) {                      /* no signal to send */
1.109     jdolecek 1035:                        p->p_sigctx.ps_sigcheck = 0;
1.29      cgd      1036:                        return (0);
1.79      mycroft  1037:                }
1.112     lukem    1038:                                                        /* take the signal! */
                   1039:                sigdelset(&p->p_sigctx.ps_siglist, signum);
1.42      mycroft  1040:
1.29      cgd      1041:                /*
                   1042:                 * We should see pending but ignored signals
                   1043:                 * only if P_TRACED was on when they were posted.
                   1044:                 */
1.109     jdolecek 1045:                if (sigismember(&p->p_sigctx.ps_sigignore, signum) &&
1.79      mycroft  1046:                    (p->p_flag & P_TRACED) == 0)
1.29      cgd      1047:                        continue;
1.42      mycroft  1048:
1.29      cgd      1049:                if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
                   1050:                        /*
                   1051:                         * If traced, always stop, and stay
                   1052:                         * stopped until released by the debugger.
                   1053:                         */
                   1054:                        p->p_xstat = signum;
1.66      mycroft  1055:                        if ((p->p_flag & P_FSTRACE) == 0)
                   1056:                                psignal(p->p_pptr, SIGCHLD);
1.65      mycroft  1057:                        do {
1.104     thorpej  1058:                                SCHED_LOCK(s);
                   1059:                                proc_stop(p);
1.112.2.1! nathanw  1060:                                mi_switch(l, NULL);
1.104     thorpej  1061:                                SCHED_ASSERT_UNLOCKED();
                   1062:                                splx(s);
1.65      mycroft  1063:                        } while (!trace_req(p) && p->p_flag & P_TRACED);
1.29      cgd      1064:
                   1065:                        /*
1.42      mycroft  1066:                         * If we are no longer being traced, or the parent
                   1067:                         * didn't give us a signal, look for more signals.
1.29      cgd      1068:                         */
1.42      mycroft  1069:                        if ((p->p_flag & P_TRACED) == 0 || p->p_xstat == 0)
1.29      cgd      1070:                                continue;
                   1071:
                   1072:                        /*
1.42      mycroft  1073:                         * If the new signal is being masked, look for other
                   1074:                         * signals.
1.29      cgd      1075:                         */
1.42      mycroft  1076:                        signum = p->p_xstat;
1.112     lukem    1077:                        /*
                   1078:                         * `p->p_sigctx.ps_siglist |= mask' is done
                   1079:                         * in setrunnable().
                   1080:                         */
1.109     jdolecek 1081:                        if (sigismember(&p->p_sigctx.ps_sigmask, signum))
1.29      cgd      1082:                                continue;
1.112     lukem    1083:                                                        /* take the signal! */
                   1084:                        sigdelset(&p->p_sigctx.ps_siglist, signum);
1.29      cgd      1085:                }
                   1086:
1.42      mycroft  1087:                prop = sigprop[signum];
                   1088:
1.29      cgd      1089:                /*
                   1090:                 * Decide whether the signal should be returned.
                   1091:                 * Return the signal's number, or fall through
                   1092:                 * to clear it from the pending mask.
                   1093:                 */
1.109     jdolecek 1094:                switch ((long)SIGACTION(p, signum).sa_handler) {
1.29      cgd      1095:
1.33      cgd      1096:                case (long)SIG_DFL:
1.29      cgd      1097:                        /*
                   1098:                         * Don't take default actions on system processes.
                   1099:                         */
                   1100:                        if (p->p_pid <= 1) {
                   1101: #ifdef DIAGNOSTIC
                   1102:                                /*
                   1103:                                 * Are you sure you want to ignore SIGSEGV
                   1104:                                 * in init? XXX
                   1105:                                 */
1.57      christos 1106:                                printf("Process (pid %d) got signal %d\n",
1.29      cgd      1107:                                    p->p_pid, signum);
                   1108: #endif
                   1109:                                break;          /* == ignore */
                   1110:                        }
                   1111:                        /*
                   1112:                         * If there is a pending stop signal to process
                   1113:                         * with default action, stop here,
                   1114:                         * then clear the signal.  However,
                   1115:                         * if process is member of an orphaned
                   1116:                         * process group, ignore tty stop signals.
                   1117:                         */
                   1118:                        if (prop & SA_STOP) {
                   1119:                                if (p->p_flag & P_TRACED ||
                   1120:                                    (p->p_pgrp->pg_jobc == 0 &&
                   1121:                                    prop & SA_TTYSTOP))
                   1122:                                        break;  /* == ignore */
                   1123:                                p->p_xstat = signum;
                   1124:                                if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
                   1125:                                        psignal(p->p_pptr, SIGCHLD);
1.104     thorpej  1126:                                SCHED_LOCK(s);
                   1127:                                proc_stop(p);
1.112.2.1! nathanw  1128:                                mi_switch(l, NULL);
1.104     thorpej  1129:                                SCHED_ASSERT_UNLOCKED();
                   1130:                                splx(s);
1.29      cgd      1131:                                break;
                   1132:                        } else if (prop & SA_IGNORE) {
                   1133:                                /*
                   1134:                                 * Except for SIGCONT, shouldn't get here.
                   1135:                                 * Default action is to ignore; drop it.
                   1136:                                 */
                   1137:                                break;          /* == ignore */
                   1138:                        } else
1.42      mycroft  1139:                                goto keep;
1.29      cgd      1140:                        /*NOTREACHED*/
                   1141:
1.33      cgd      1142:                case (long)SIG_IGN:
1.29      cgd      1143:                        /*
                   1144:                         * Masking above should prevent us ever trying
                   1145:                         * to take action on an ignored signal other
                   1146:                         * than SIGCONT, unless process is traced.
                   1147:                         */
                   1148:                        if ((prop & SA_CONT) == 0 &&
                   1149:                            (p->p_flag & P_TRACED) == 0)
1.57      christos 1150:                                printf("issignal\n");
1.29      cgd      1151:                        break;          /* == ignore */
                   1152:
                   1153:                default:
                   1154:                        /*
                   1155:                         * This signal has an action, let
                   1156:                         * postsig() process it.
                   1157:                         */
1.42      mycroft  1158:                        goto keep;
1.29      cgd      1159:                }
                   1160:        }
                   1161:        /* NOTREACHED */
1.42      mycroft  1162:
1.112     lukem    1163:  keep:
                   1164:                                                /* leave the signal for later */
                   1165:        sigaddset(&p->p_sigctx.ps_siglist, signum);
1.110     thorpej  1166:        CHECKSIGS(p);
1.42      mycroft  1167:        return (signum);
1.29      cgd      1168: }
                   1169:
                   1170: /*
                   1171:  * Put the argument process into the stopped state and notify the parent
                   1172:  * via wakeup.  Signals are handled elsewhere.  The process must not be
                   1173:  * on the run queue.
                   1174:  */
1.104     thorpej  1175: static void
1.112     lukem    1176: proc_stop(struct proc *p)
1.29      cgd      1177: {
1.112.2.1! nathanw  1178:        struct lwp *l;
1.29      cgd      1179:
1.104     thorpej  1180:        SCHED_ASSERT_LOCKED();
                   1181:
1.112.2.1! nathanw  1182:        /* XXX lock process LWP state */
1.29      cgd      1183:        p->p_stat = SSTOP;
                   1184:        p->p_flag &= ~P_WAITED;
1.112.2.1! nathanw  1185:
        !          1186:
        !          1187:        /*
        !          1188:         * Put as many LWP's as possible in stopped state.
        !          1189:         * Any in uninterruptable sleep will notice the stopped state as
        !          1190:         * they try to return.
        !          1191:         */
        !          1192:
        !          1193:        for (l = LIST_FIRST(&p->p_lwps); l != NULL;
        !          1194:             l = LIST_NEXT(l, l_sibling)) {
        !          1195:                if (l->l_stat == LSONPROC) {
        !          1196:                        /* XXX SMP this assumes that a LWP that is LSONPROC
        !          1197:                         * is curproc and hence is about to be mi_switched
        !          1198:                         * away; the only callers of proc_stop() are:
        !          1199:                         * - psignal
        !          1200:                         * - issignal()
        !          1201:                         * For the former, proc_stop() is only called when
        !          1202:                         * no processes are running, so we don't worry.
        !          1203:                         * For the latter, proc_stop() is called right
        !          1204:                         * before mi_switch().
        !          1205:                         */
        !          1206:                        l->l_stat = LSSTOP;
        !          1207:                        p->p_nrlwps--;
        !          1208:                } else if (l->l_stat == LSRUN) {
        !          1209:                        /* Remove LWP from the run queue */
        !          1210:                        remrunqueue(l);
        !          1211:                        l->l_stat = LSSTOP;
        !          1212:                        p->p_nrlwps--;
        !          1213:                } else if (l->l_stat == LSSLEEP) {
        !          1214:                        /* Note: this puts all sleeping LWPs into LSSTOP.
        !          1215:                         * Formerly, uninterruptably sleeping procs were
        !          1216:                         * left to discover the STOP signal on their
        !          1217:                         * way back to userspace, but that's harder
        !          1218:                         * with multiple LWPs.
        !          1219:                         * XXX This shou;d be okay, but.....
        !          1220:                         */
        !          1221:                        l->l_stat = LSSTOP;
        !          1222:                } else if ((l->l_stat == LSSUSPENDED) ||
        !          1223:                    (l->l_stat == LSZOMB) ||
        !          1224:                        (l->l_stat == LSDEAD)) {
        !          1225:                        /* Don't do anything. These guys aren't going anywhere.
        !          1226:                         */
        !          1227:                }
        !          1228: #ifdef DIAGNOSTIC
        !          1229:                else {
        !          1230:                        panic("proc_stop: process %d lwp %d "
        !          1231:                              "in unstoppable state %d.\n",
        !          1232:                            p->p_pid, l->l_lid, l->l_stat);
        !          1233:                }
        !          1234: #endif
        !          1235:        }
        !          1236:        /* XXX unlock process LWP state */
        !          1237:
1.104     thorpej  1238:        sched_wakeup((caddr_t)p->p_pptr);
1.29      cgd      1239: }
                   1240:
1.112.2.1! nathanw  1241: struct lwp *
        !          1242: proc_unstop(p)
        !          1243:        struct proc *p;
        !          1244: {
        !          1245:        struct lwp *l, *lr = NULL;
        !          1246:
        !          1247:        SCHED_ASSERT_LOCKED();
        !          1248:
        !          1249:        /* Our caller will want to invoke setrunnable() on whatever we return.
        !          1250:         * XXX what if everyone was asleep when the process was stopped?
        !          1251:         * Yuck.
        !          1252:         */
        !          1253:
        !          1254:        p->p_stat = SACTIVE;
        !          1255:        for (l = LIST_FIRST(&p->p_lwps); l != NULL;
        !          1256:             l = LIST_NEXT(l, l_sibling))
        !          1257:                if (l->l_stat == LSSTOP) {
        !          1258:                        if (l->l_wchan == 0) {
        !          1259:                                p->p_nrlwps++;
        !          1260:                                if (lr == NULL)
        !          1261:                                        lr = l;
        !          1262:                                else
        !          1263:                                        setrunnable(l);
        !          1264:                        }
        !          1265:                        else
        !          1266:                                l->l_stat = LSSLEEP;
        !          1267:                }
        !          1268:
        !          1269:        return lr;
        !          1270: }
        !          1271:
1.29      cgd      1272: /*
                   1273:  * Take the action for the specified signal
                   1274:  * from the current set of pending signals.
                   1275:  */
                   1276: void
1.112     lukem    1277: postsig(int signum)
1.29      cgd      1278: {
1.112.2.1! nathanw  1279:        struct lwp *l;
1.112     lukem    1280:        struct proc     *p;
                   1281:        struct sigacts  *ps;
                   1282:        sig_t           action;
                   1283:        u_long          code;
                   1284:        sigset_t        *returnmask;
1.29      cgd      1285:
1.112.2.1! nathanw  1286:        l = curproc;
        !          1287:        p = l->l_proc;
1.112     lukem    1288:        ps = p->p_sigacts;
1.29      cgd      1289: #ifdef DIAGNOSTIC
                   1290:        if (signum == 0)
                   1291:                panic("postsig");
                   1292: #endif
1.106     thorpej  1293:
                   1294:        KERNEL_PROC_LOCK(p);
                   1295:
1.109     jdolecek 1296:        sigdelset(&p->p_sigctx.ps_siglist, signum);
                   1297:        action = SIGACTION_PS(ps, signum).sa_handler;
1.29      cgd      1298: #ifdef KTRACE
                   1299:        if (KTRPOINT(p, KTR_PSIG))
1.100     sommerfe 1300:                ktrpsig(p,
1.109     jdolecek 1301:                    signum, action, p->p_sigctx.ps_flags & SAS_OLDMASK ?
                   1302:                    &p->p_sigctx.ps_oldmask : &p->p_sigctx.ps_sigmask, 0);
1.29      cgd      1303: #endif
                   1304:        if (action == SIG_DFL) {
                   1305:                /*
                   1306:                 * Default action, where the default is to kill
                   1307:                 * the process.  (Other cases were ignored above.)
                   1308:                 */
1.112.2.1! nathanw  1309:                sigexit(l, signum);
1.29      cgd      1310:                /* NOTREACHED */
                   1311:        } else {
                   1312:                /*
                   1313:                 * If we get here, the signal must be caught.
                   1314:                 */
                   1315: #ifdef DIAGNOSTIC
1.112     lukem    1316:                if (action == SIG_IGN ||
                   1317:                    sigismember(&p->p_sigctx.ps_sigmask, signum))
1.29      cgd      1318:                        panic("postsig action");
                   1319: #endif
                   1320:                /*
                   1321:                 * Set the new mask value and also defer further
                   1322:                 * occurences of this signal.
                   1323:                 *
                   1324:                 * Special case: user has done a sigpause.  Here the
                   1325:                 * current mask is not of interest, but rather the
                   1326:                 * mask from before the sigpause is what we want
                   1327:                 * restored after the signal processing is completed.
                   1328:                 */
1.109     jdolecek 1329:                if (p->p_sigctx.ps_flags & SAS_OLDMASK) {
                   1330:                        returnmask = &p->p_sigctx.ps_oldmask;
                   1331:                        p->p_sigctx.ps_flags &= ~SAS_OLDMASK;
1.29      cgd      1332:                } else
1.109     jdolecek 1333:                        returnmask = &p->p_sigctx.ps_sigmask;
1.29      cgd      1334:                p->p_stats->p_ru.ru_nsignals++;
1.109     jdolecek 1335:                if (p->p_sigctx.ps_sig != signum) {
1.29      cgd      1336:                        code = 0;
                   1337:                } else {
1.109     jdolecek 1338:                        code = p->p_sigctx.ps_code;
                   1339:                        p->p_sigctx.ps_code = 0;
                   1340:                        p->p_sigctx.ps_sig = 0;
1.29      cgd      1341:                }
1.41      christos 1342:                (*p->p_emul->e_sendsig)(action, signum, returnmask, code);
1.105     thorpej  1343:                (void) splsched();      /* XXXSMP */
1.112     lukem    1344:                sigplusset(&SIGACTION_PS(ps, signum).sa_mask,
                   1345:                    &p->p_sigctx.ps_sigmask);
1.109     jdolecek 1346:                if (SIGACTION_PS(ps, signum).sa_flags & SA_RESETHAND) {
                   1347:                        sigdelset(&p->p_sigctx.ps_sigcatch, signum);
1.79      mycroft  1348:                        if (signum != SIGCONT && sigprop[signum] & SA_IGNORE)
1.109     jdolecek 1349:                                sigaddset(&p->p_sigctx.ps_sigignore, signum);
                   1350:                        SIGACTION_PS(ps, signum).sa_handler = SIG_DFL;
1.79      mycroft  1351:                }
1.104     thorpej  1352:                (void) spl0();          /* XXXSMP */
1.29      cgd      1353:        }
1.106     thorpej  1354:
                   1355:        KERNEL_PROC_UNLOCK(p);
1.29      cgd      1356: }
                   1357:
                   1358: /*
                   1359:  * Kill the current process for stated reason.
                   1360:  */
1.52      christos 1361: void
1.112     lukem    1362: killproc(struct proc *p, char *why)
1.29      cgd      1363: {
                   1364:
                   1365:        log(LOG_ERR, "pid %d was killed: %s\n", p->p_pid, why);
                   1366:        uprintf("sorry, pid %d was killed: %s\n", p->p_pid, why);
                   1367:        psignal(p, SIGKILL);
                   1368: }
                   1369:
                   1370: /*
                   1371:  * Force the current process to exit with the specified signal, dumping core
                   1372:  * if appropriate.  We bypass the normal tests for masked and caught signals,
                   1373:  * allowing unrecoverable failures to terminate the process without changing
                   1374:  * signal state.  Mark the accounting record with the signal termination.
                   1375:  * If dumping core, save the signal number for the debugger.  Calls exit and
                   1376:  * does not return.
                   1377:  */
1.96      fair     1378:
1.97      fair     1379: #if defined(DEBUG)
1.96      fair     1380: int    kern_logsigexit = 1;    /* not static to make public for sysctl */
                   1381: #else
                   1382: int    kern_logsigexit = 0;    /* not static to make public for sysctl */
                   1383: #endif
                   1384:
1.102     sommerfe 1385: static const char logcoredump[] =
1.96      fair     1386:        "pid %d (%s), uid %d: exited on signal %d (core dumped)\n";
1.102     sommerfe 1387: static const char lognocoredump[] =
1.96      fair     1388:        "pid %d (%s), uid %d: exited on signal %d (core not dumped, err = %d)\n";
                   1389:
1.52      christos 1390: void
1.112.2.1! nathanw  1391: sigexit(struct lwp *l, int signum)
1.29      cgd      1392: {
1.112.2.1! nathanw  1393:        struct proc     *p;
        !          1394:        int             error, exitsig;
1.96      fair     1395:
1.112.2.1! nathanw  1396:        p = l->l_proc;
1.112     lukem    1397:        exitsig = signum;
1.29      cgd      1398:        p->p_acflag |= AXSIG;
                   1399:        if (sigprop[signum] & SA_CORE) {
1.109     jdolecek 1400:                p->p_sigctx.ps_sig = signum;
1.112.2.1! nathanw  1401:                if ((error = coredump(l)) == 0)
1.102     sommerfe 1402:                        exitsig |= WCOREFLAG;
                   1403:
                   1404:                if (kern_logsigexit) {
                   1405:                        int uid = p->p_cred && p->p_ucred ?
                   1406:                                p->p_ucred->cr_uid : -1;
                   1407:
                   1408:                        if (error)
                   1409:                                log(LOG_INFO, lognocoredump, p->p_pid,
                   1410:                                    p->p_comm, uid, signum, error);
                   1411:                        else
                   1412:                                log(LOG_INFO, logcoredump, p->p_pid,
                   1413:                                    p->p_comm, uid, signum);
1.96      fair     1414:                }
                   1415:
1.29      cgd      1416:        }
1.96      fair     1417:
1.112.2.1! nathanw  1418:        exit1(l, W_EXITCODE(0, exitsig));
1.29      cgd      1419:        /* NOTREACHED */
                   1420: }
                   1421:
                   1422: /*
1.75      nathanw  1423:  * Dump core, into a file named "progname.core" or "core" (depending on the
                   1424:  * value of shortcorename), unless the process was setuid/setgid.
1.29      cgd      1425:  */
                   1426: int
1.112.2.1! nathanw  1427: coredump(struct lwp *l)
1.29      cgd      1428: {
1.112     lukem    1429:        struct vnode            *vp;
1.112.2.1! nathanw  1430:        struct proc             *p;
1.112     lukem    1431:        struct vmspace          *vm;
                   1432:        struct ucred            *cred;
                   1433:        struct nameidata        nd;
                   1434:        struct vattr            vattr;
                   1435:        int                     error, error1;
                   1436:        char                    name[MAXPATHLEN];
                   1437:        struct core             core;
                   1438:
1.112.2.1! nathanw  1439:        p = l->l_proc;
1.112     lukem    1440:        vm = p->p_vmspace;
                   1441:        cred = p->p_cred->pc_ucred;
1.29      cgd      1442:
1.59      cgd      1443:        /*
                   1444:         * Make sure the process has not set-id, to prevent data leaks.
                   1445:         */
1.58      mrg      1446:        if (p->p_flag & P_SUGID)
1.59      cgd      1447:                return (EPERM);
                   1448:
                   1449:        /*
                   1450:         * Refuse to core if the data + stack + user size is larger than
                   1451:         * the core dump limit.  XXX THIS IS WRONG, because of mapped
                   1452:         * data.
                   1453:         */
1.30      deraadt  1454:        if (USPACE + ctob(vm->vm_dsize + vm->vm_ssize) >=
1.29      cgd      1455:            p->p_rlimit[RLIMIT_CORE].rlim_cur)
1.59      cgd      1456:                return (EFBIG);         /* better error code? */
                   1457:
                   1458:        /*
                   1459:         * The core dump will go in the current working directory.  Make
1.80      pk       1460:         * sure that the directory is still there and that the mount flags
                   1461:         * allow us to write core dumps there.
1.59      cgd      1462:         */
1.88      thorpej  1463:        vp = p->p_cwdi->cwdi_cdir;
1.80      pk       1464:        if (vp->v_mount == NULL ||
                   1465:            (vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0)
1.59      cgd      1466:                return (EPERM);
                   1467:
1.100     sommerfe 1468:        error = build_corename(p, name);
1.94      bouyer   1469:        if (error)
                   1470:                return error;
                   1471:
1.112.2.1! nathanw  1472:        /* We don't want to switch away from crashing. */
        !          1473:        /* XXX multiprocessor: stop LWPs on other processors. */
        !          1474:        if (l->l_flag & L_SA)
        !          1475:                l->l_flag &= ~L_SA;
        !          1476:
1.93      bouyer   1477:        NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
                   1478:        error = vn_open(&nd, O_CREAT | FWRITE | FNOSYMLINK, S_IRUSR | S_IWUSR);
1.52      christos 1479:        if (error)
1.29      cgd      1480:                return (error);
                   1481:        vp = nd.ni_vp;
                   1482:
                   1483:        /* Don't dump to non-regular files or files with links. */
                   1484:        if (vp->v_type != VREG ||
                   1485:            VOP_GETATTR(vp, &vattr, cred, p) || vattr.va_nlink != 1) {
1.59      cgd      1486:                error = EINVAL;
1.29      cgd      1487:                goto out;
                   1488:        }
                   1489:        VATTR_NULL(&vattr);
                   1490:        vattr.va_size = 0;
1.37      mycroft  1491:        VOP_LEASE(vp, p, cred, LEASE_WRITE);
1.29      cgd      1492:        VOP_SETATTR(vp, &vattr, cred, p);
                   1493:        p->p_acflag |= ACORE;
1.95      eeh      1494:
                   1495: #if COMPAT_NETBSD32
                   1496:        if (p->p_flag & P_32)
                   1497:                return (coredump32(p, vp));
                   1498: #endif
1.67      mycroft  1499: #if 0
                   1500:        /*
                   1501:         * XXX
                   1502:         * It would be nice if we at least dumped the signal state (and made it
                   1503:         * available at run time to the debugger, as well), but this code
                   1504:         * hasn't actually had any effect for a long time, since we don't dump
                   1505:         * the user area.  For now, it's dead.
                   1506:         */
1.78      perry    1507:        memcpy(&p->p_addr->u_kproc.kp_proc, p, sizeof(struct proc));
1.29      cgd      1508:        fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
1.67      mycroft  1509: #endif
1.29      cgd      1510:
                   1511:        core.c_midmag = 0;
                   1512:        strncpy(core.c_name, p->p_comm, MAXCOMLEN);
                   1513:        core.c_nseg = 0;
1.109     jdolecek 1514:        core.c_signo = p->p_sigctx.ps_sig;
                   1515:        core.c_ucode = p->p_sigctx.ps_code;
1.29      cgd      1516:        core.c_cpusize = 0;
                   1517:        core.c_tsize = (u_long)ctob(vm->vm_tsize);
                   1518:        core.c_dsize = (u_long)ctob(vm->vm_dsize);
                   1519:        core.c_ssize = (u_long)round_page(ctob(vm->vm_ssize));
1.112.2.1! nathanw  1520:        error = cpu_coredump(l, vp, cred, &core);
1.29      cgd      1521:        if (error)
                   1522:                goto out;
1.111     nathanw  1523:        /*
                   1524:         * uvm_coredump() spits out all appropriate segments.
                   1525:         * All that's left to do is to write the core header.
                   1526:         */
                   1527:        error = uvm_coredump(p, vp, cred, &core);
                   1528:        if (error)
                   1529:                goto out;
                   1530:        error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&core,
                   1531:            (int)core.c_hdrsize, (off_t)0,
                   1532:            UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p);
1.112     lukem    1533:  out:
1.71      fvdl     1534:        VOP_UNLOCK(vp, 0);
1.29      cgd      1535:        error1 = vn_close(vp, FWRITE, cred, p);
                   1536:        if (error == 0)
                   1537:                error = error1;
                   1538:        return (error);
                   1539: }
1.95      eeh      1540:
                   1541: #if COMPAT_NETBSD32
                   1542: /*
                   1543:  * Same as coredump, but generates a 32-bit image.
                   1544:  */
                   1545: int
1.112     lukem    1546: coredump32(struct proc *p, struct vnode *vp)
1.95      eeh      1547: {
1.112     lukem    1548:        struct vmspace  *vm;
                   1549:        struct ucred    *cred;
                   1550:        int             error, error1;
                   1551:        struct core32   core;
1.95      eeh      1552:
1.112     lukem    1553:        vm = p->p_vmspace;
                   1554:        cred = p->p_cred->pc_ucred;
1.95      eeh      1555: #if 0
                   1556:        /*
                   1557:         * XXX
                   1558:         * It would be nice if we at least dumped the signal state (and made it
                   1559:         * available at run time to the debugger, as well), but this code
                   1560:         * hasn't actually had any effect for a long time, since we don't dump
                   1561:         * the user area.  For now, it's dead.
                   1562:         */
                   1563:        memcpy(&p->p_addr->u_kproc.kp_proc, p, sizeof(struct proc));
                   1564:        fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
                   1565: #endif
                   1566:
                   1567:        core.c_midmag = 0;
                   1568:        strncpy(core.c_name, p->p_comm, MAXCOMLEN);
                   1569:        core.c_nseg = 0;
1.109     jdolecek 1570:        core.c_signo = p->p_sigctx.ps_sig;
                   1571:        core.c_ucode = p->p_sigctx.ps_code;
1.95      eeh      1572:        core.c_cpusize = 0;
                   1573:        core.c_tsize = (u_long)ctob(vm->vm_tsize);
                   1574:        core.c_dsize = (u_long)ctob(vm->vm_dsize);
                   1575:        core.c_ssize = (u_long)round_page(ctob(vm->vm_ssize));
                   1576:        error = cpu_coredump32(p, vp, cred, &core);
                   1577:        if (error)
                   1578:                goto out;
1.111     nathanw  1579:        /*
                   1580:         * uvm_coredump() spits out all appropriate segments.
                   1581:         * All that's left to do is to write the core header.
                   1582:         */
                   1583:        error = uvm_coredump32(p, vp, cred, &core);
                   1584:        if (error)
                   1585:                goto out;
                   1586:        error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&core,
                   1587:            (int)core.c_hdrsize, (off_t)0,
                   1588:            UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p);
1.112     lukem    1589:  out:
1.95      eeh      1590:        VOP_UNLOCK(vp, 0);
                   1591:        error1 = vn_close(vp, FWRITE, cred, p);
                   1592:        if (error == 0)
                   1593:                error = error1;
                   1594:        return (error);
                   1595: }
                   1596: #endif
1.29      cgd      1597:
                   1598: /*
                   1599:  * Nonexistent system call-- signal process (may want to handle it).
                   1600:  * Flag error in case process won't see signal immediately (blocked or ignored).
                   1601:  */
                   1602: /* ARGSUSED */
                   1603: int
1.112.2.1! nathanw  1604: sys_nosys(struct lwp *l, void *v, register_t *retval)
1.29      cgd      1605: {
1.112.2.1! nathanw  1606:        struct proc     *p;
1.29      cgd      1607:
1.112.2.1! nathanw  1608:        p = l->l_proc;
1.29      cgd      1609:        psignal(p, SIGSYS);
1.36      cgd      1610:        return (ENOSYS);
1.94      bouyer   1611: }
                   1612:
                   1613: static int
1.112     lukem    1614: build_corename(struct proc *p, char dst[MAXPATHLEN])
1.94      bouyer   1615: {
1.112     lukem    1616:        const char      *s;
                   1617:        char            *d, *end;
                   1618:        int             i;
1.100     sommerfe 1619:
1.107     enami    1620:        for (s = p->p_limit->pl_corename, d = dst, end = d + MAXPATHLEN;
1.94      bouyer   1621:            *s != '\0'; s++) {
                   1622:                if (*s == '%') {
1.107     enami    1623:                        switch (*(s + 1)) {
1.94      bouyer   1624:                        case 'n':
1.107     enami    1625:                                i = snprintf(d, end - d, "%s", p->p_comm);
1.94      bouyer   1626:                                break;
                   1627:                        case 'p':
1.107     enami    1628:                                i = snprintf(d, end - d, "%d", p->p_pid);
1.94      bouyer   1629:                                break;
                   1630:                        case 'u':
1.107     enami    1631:                                i = snprintf(d, end - d, "%s",
1.100     sommerfe 1632:                                    p->p_pgrp->pg_session->s_login);
1.94      bouyer   1633:                                break;
                   1634:                        case 't':
1.107     enami    1635:                                i = snprintf(d, end - d, "%ld",
1.100     sommerfe 1636:                                    p->p_stats->p_start.tv_sec);
1.94      bouyer   1637:                                break;
                   1638:                        default:
                   1639:                                goto copy;
                   1640:                        }
                   1641:                        d += i;
                   1642:                        s++;
                   1643:                } else {
1.112     lukem    1644:  copy:                 *d = *s;
1.94      bouyer   1645:                        d++;
                   1646:                }
1.107     enami    1647:                if (d >= end)
                   1648:                        return (ENAMETOOLONG);
1.94      bouyer   1649:        }
                   1650:        *d = '\0';
1.112.2.1! nathanw  1651:        return 0;
1.108     jdolecek 1652: }
                   1653:
1.112.2.1! nathanw  1654: void
        !          1655: getucontext(struct lwp *l, ucontext_t *ucp)
        !          1656: {
        !          1657:        struct proc     *p;
        !          1658:
        !          1659:        p = l->l_proc;
        !          1660:
        !          1661:        ucp->uc_flags = 0;
        !          1662:        ucp->uc_link = l->l_ctxlink;
        !          1663:
        !          1664:        (void)sigprocmask1(p, 0, NULL, &ucp->uc_sigmask);
        !          1665:        ucp->uc_flags |= _UC_SIGMASK;
        !          1666:
        !          1667:        /*
        !          1668:         * The (unsupplied) definition of the `current execution stack'
        !          1669:         * in the System V Interface Definition appears to allow returning
        !          1670:         * the main context stack.
        !          1671:         */
        !          1672:        if ((p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK) == 0) {
        !          1673:                ucp->uc_stack.ss_sp = (void *)USRSTACK;
        !          1674:                ucp->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize);
        !          1675:                ucp->uc_stack.ss_flags = 0;     /* XXX, def. is Very Fishy */
        !          1676:        } else {
        !          1677:                /* Simply copy alternate signal execution stack. */
        !          1678:                ucp->uc_stack = p->p_sigctx.ps_sigstk;
        !          1679:        }
        !          1680:        ucp->uc_flags |= _UC_STACK;
        !          1681:
        !          1682:        cpu_getmcontext(l, &ucp->uc_mcontext, &ucp->uc_flags);
        !          1683: }
        !          1684:
        !          1685: /* ARGSUSED */
        !          1686: int
        !          1687: sys_getcontext(struct lwp *l, void *v, register_t *retval)
        !          1688: {
        !          1689:        struct sys_getcontext_args /* {
        !          1690:                syscallarg(struct __ucontext *) ucp;
        !          1691:        } */ *uap = v;
        !          1692:        ucontext_t uc;
        !          1693:
        !          1694:        getucontext(l, &uc);
        !          1695:
        !          1696:        return (copyout(&uc, SCARG(uap, ucp), sizeof (*SCARG(uap, ucp))));
        !          1697: }
        !          1698:
        !          1699: int
        !          1700: setucontext(struct lwp *l, const ucontext_t *ucp)
        !          1701: {
        !          1702:        struct proc     *p;
        !          1703:        int             error;
        !          1704:
        !          1705:        p = l->l_proc;
        !          1706:        if ((error = cpu_setmcontext(l, &ucp->uc_mcontext, ucp->uc_flags)) != 0)
        !          1707:                return (error);
        !          1708:        l->l_ctxlink = ucp->uc_link;
        !          1709:        /*
        !          1710:         * We might want to take care of the stack portion here but currently
        !          1711:         * don't; see the comment in getucontext().
        !          1712:         */
        !          1713:        if ((ucp->uc_flags & _UC_SIGMASK) != 0)
        !          1714:                sigprocmask1(p, SIG_SETMASK, &ucp->uc_sigmask, NULL);
        !          1715:
        !          1716:        return 0;
        !          1717: }
        !          1718:
        !          1719: /* ARGSUSED */
        !          1720: int
        !          1721: sys_setcontext(struct lwp *l, void *v, register_t *retval)
        !          1722: {
        !          1723:        struct sys_setcontext_args /* {
        !          1724:                syscallarg(const ucontext_t *) ucp;
        !          1725:        } */ *uap = v;
        !          1726:        ucontext_t uc;
        !          1727:        int error;
        !          1728:
        !          1729:        if (SCARG(uap, ucp) == NULL)    /* i.e. end of uc_link chain */
        !          1730:                exit1(l, W_EXITCODE(0, 0));
        !          1731:        else if ((error = copyin(SCARG(uap, ucp), &uc, sizeof (uc))) != 0 ||
        !          1732:            (error = setucontext(l, &uc)) != 0)
        !          1733:                return (error);
        !          1734:
        !          1735:        return (EJUSTRETURN);
        !          1736: }
        !          1737:
        !          1738:
1.108     jdolecek 1739: /*
                   1740:  * Returns true if signal is ignored or masked for passed process.
                   1741:  */
                   1742: int
1.112     lukem    1743: sigismasked(struct proc *p, int sig)
1.108     jdolecek 1744: {
1.112     lukem    1745:
1.109     jdolecek 1746:        return sigismember(&p->p_sigctx.ps_sigignore, SIGTTOU)
                   1747:                || sigismember(&p->p_sigctx.ps_sigmask, SIGTTOU);
1.29      cgd      1748: }
1.112.2.1! nathanw  1749:

CVSweb <webmaster@jp.NetBSD.org>