Annotation of kernel/bsd/kern/kern_sig.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /* Copyright (c) 1995-1998 Apple Computer, Inc. All Rights Reserved */
        !            26: /*
        !            27:  * Copyright (c) 1982, 1986, 1989, 1991, 1993
        !            28:  *     The Regents of the University of California.  All rights reserved.
        !            29:  * (c) UNIX System Laboratories, Inc.
        !            30:  * All or some portions of this file are derived from material licensed
        !            31:  * to the University of California by American Telephone and Telegraph
        !            32:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
        !            33:  * the permission of UNIX System Laboratories, Inc.
        !            34:  *
        !            35:  * Redistribution and use in source and binary forms, with or without
        !            36:  * modification, are permitted provided that the following conditions
        !            37:  * are met:
        !            38:  * 1. Redistributions of source code must retain the above copyright
        !            39:  *    notice, this list of conditions and the following disclaimer.
        !            40:  * 2. Redistributions in binary form must reproduce the above copyright
        !            41:  *    notice, this list of conditions and the following disclaimer in the
        !            42:  *    documentation and/or other materials provided with the distribution.
        !            43:  * 3. All advertising materials mentioning features or use of this software
        !            44:  *    must display the following acknowledgement:
        !            45:  *     This product includes software developed by the University of
        !            46:  *     California, Berkeley and its contributors.
        !            47:  * 4. Neither the name of the University nor the names of its contributors
        !            48:  *    may be used to endorse or promote products derived from this software
        !            49:  *    without specific prior written permission.
        !            50:  *
        !            51:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            52:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            53:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            54:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            55:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            56:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            57:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            58:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            59:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            60:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            61:  * SUCH DAMAGE.
        !            62:  *
        !            63:  *     @(#)kern_sig.c  8.7 (Berkeley) 4/18/94
        !            64:  */
        !            65: 
        !            66: #define        SIGPROP         /* include signal properties table */
        !            67: #include <sys/param.h>
        !            68: #include <sys/signalvar.h>
        !            69: #include <sys/resourcevar.h>
        !            70: #include <sys/namei.h>
        !            71: #include <sys/vnode.h>
        !            72: #include <sys/proc.h>
        !            73: #include <sys/systm.h>
        !            74: #include <sys/timeb.h>
        !            75: #include <sys/times.h>
        !            76: #include <sys/buf.h>
        !            77: #include <sys/acct.h>
        !            78: #include <sys/file.h>
        !            79: #include <sys/kernel.h>
        !            80: #include <sys/wait.h>
        !            81: #include <sys/ktrace.h>
        !            82: #include <sys/syslog.h>
        !            83: #include <sys/stat.h>
        !            84: 
        !            85: #include <sys/mount.h>
        !            86: 
        !            87: #include <machine/cpu.h>
        !            88: #include <machine/spl.h>
        !            89: 
        !            90: #include <sys/vm.h>
        !            91: #include <sys/user.h>          /* for coredump */
        !            92: 
        !            93: void stop __P((struct proc *p));
        !            94: int cansignal __P((struct proc *, struct pcred *, struct proc *, int));
        !            95: int killpg1 __P((struct proc *, int, int, int));
        !            96: void sigexit __P((struct proc *, int));
        !            97: void setsigvec __P((struct proc *, int, struct sigaction *));
        !            98: void exit1 __P((struct proc *, int));
        !            99: 
        !           100: /*
        !           101:  * Can process p, with pcred pc, send the signal signum to process q?
        !           102:  */
        !           103: int
        !           104: cansignal(p, pc, q, signum)
        !           105:        struct proc *p;
        !           106:        struct pcred *pc;
        !           107:        struct proc *q;
        !           108:        int signum;
        !           109: {
        !           110:        if (pc->pc_ucred->cr_uid == 0)
        !           111:                return (1);             /* root can always signal */
        !           112: 
        !           113:        if (signum == SIGCONT && q->p_session == p->p_session)
        !           114:                return (1);             /* SIGCONT in session */
        !           115: 
        !           116:        /*
        !           117:         * Using kill(), only certain signals can be sent to setugid
        !           118:         * child processes
        !           119:         */
        !           120:        if (q->p_flag & P_SUGID) {
        !           121:                switch (signum) {
        !           122:                case 0:
        !           123:                case SIGKILL:
        !           124:                case SIGINT:
        !           125:                case SIGTERM:
        !           126:                case SIGSTOP:
        !           127:                case SIGTTIN:
        !           128:                case SIGTTOU:
        !           129:                case SIGTSTP:
        !           130:                case SIGHUP:
        !           131:                case SIGUSR1:
        !           132:                case SIGUSR2:
        !           133:                        if (pc->p_ruid == q->p_cred->p_ruid ||
        !           134:                            pc->pc_ucred->cr_uid == q->p_cred->p_ruid ||
        !           135:                            pc->p_ruid == q->p_ucred->cr_uid ||
        !           136:                            pc->pc_ucred->cr_uid == q->p_ucred->cr_uid)
        !           137:                                return (1);
        !           138:                }
        !           139:                return (0);
        !           140:        }
        !           141: 
        !           142:        /* XXX
        !           143:         * because the P_SUGID test exists, this has extra tests which
        !           144:         * could be removed.
        !           145:         */
        !           146:        if (pc->p_ruid == q->p_cred->p_ruid ||
        !           147:            pc->p_ruid == q->p_cred->p_svuid ||
        !           148:            pc->pc_ucred->cr_uid == q->p_cred->p_ruid ||
        !           149:            pc->pc_ucred->cr_uid == q->p_cred->p_svuid ||
        !           150:            pc->p_ruid == q->p_ucred->cr_uid ||
        !           151:            pc->pc_ucred->cr_uid == q->p_ucred->cr_uid)
        !           152:                return (1);
        !           153:        return (0);
        !           154: }
        !           155: 
        !           156: struct sigaction_args {
        !           157:        int     signum;
        !           158:        struct sigaction *nsa;
        !           159:        struct sigaction *osa;
        !           160: };
        !           161: /* ARGSUSED */
        !           162: int
        !           163: sigaction(p, uap, retval)
        !           164:        struct proc *p;
        !           165:        register struct sigaction_args *uap;
        !           166:        register_t *retval;
        !           167: {
        !           168:        struct sigaction vec;
        !           169:        register struct sigaction *sa;
        !           170:        register struct sigacts *ps = p->p_sigacts;
        !           171:        register int signum;
        !           172:        int bit, error;
        !           173: 
        !           174:        signum = uap->signum;
        !           175:        if (signum <= 0 || signum >= NSIG ||
        !           176:            signum == SIGKILL || signum == SIGSTOP)
        !           177:                return (EINVAL);
        !           178:        sa = &vec;
        !           179:        if (uap->osa) {
        !           180:                sa->sa_handler = ps->ps_sigact[signum];
        !           181:                sa->sa_mask = ps->ps_catchmask[signum];
        !           182:                bit = sigmask(signum);
        !           183:                sa->sa_flags = 0;
        !           184:                if ((ps->ps_sigonstack & bit) != 0)
        !           185:                        sa->sa_flags |= SA_ONSTACK;
        !           186:                if ((ps->ps_sigintr & bit) == 0)
        !           187:                        sa->sa_flags |= SA_RESTART;
        !           188:                if (p->p_flag & P_NOCLDSTOP)
        !           189:                        sa->sa_flags |= SA_NOCLDSTOP;
        !           190:                if (error = copyout((caddr_t)sa, (caddr_t)uap->osa,
        !           191:                    sizeof (vec)))
        !           192:                        return (error);
        !           193:        }
        !           194:        if (uap->nsa) {
        !           195:                if (error = copyin((caddr_t)uap->nsa, (caddr_t)sa,
        !           196:                    sizeof (vec)))
        !           197:                        return (error);
        !           198:                setsigvec(p, signum, sa);
        !           199:        }
        !           200:        return (0);
        !           201: }
        !           202: 
        !           203: void
        !           204: setsigvec(p, signum, sa)
        !           205:        register struct proc *p;
        !           206:        int signum;
        !           207:        register struct sigaction *sa;
        !           208: {
        !           209:        register struct sigacts *ps = p->p_sigacts;
        !           210:        register int bit;
        !           211: 
        !           212:        bit = sigmask(signum);
        !           213:        /*
        !           214:         * Change setting atomically.
        !           215:         */
        !           216:        (void) splhigh();
        !           217:        simple_lock(&p->siglock);
        !           218:        ps->ps_sigact[signum] = sa->sa_handler;
        !           219:        ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask;
        !           220:        if ((sa->sa_flags & SA_RESTART) == 0)
        !           221:                ps->ps_sigintr |= bit;
        !           222:        else
        !           223:                ps->ps_sigintr &= ~bit;
        !           224:        if (sa->sa_flags & SA_ONSTACK)
        !           225:                ps->ps_sigonstack |= bit;
        !           226:        else
        !           227:                ps->ps_sigonstack &= ~bit;
        !           228:        if (sa->sa_flags & SA_USERTRAMP)
        !           229:                ps->ps_usertramp |= bit;
        !           230:        else
        !           231:                ps->ps_usertramp &= ~bit;
        !           232:        if (signum == SIGCHLD) {
        !           233:                if (sa->sa_flags & SA_NOCLDSTOP)
        !           234:                        p->p_flag |= P_NOCLDSTOP;
        !           235:                else
        !           236:                        p->p_flag &= ~P_NOCLDSTOP;
        !           237:        }
        !           238:        /*
        !           239:         * Set bit in p_sigignore for signals that are set to SIG_IGN,
        !           240:         * and for signals set to SIG_DFL where the default is to ignore.
        !           241:         * However, don't put SIGCONT in p_sigignore,
        !           242:         * as we have to restart the process.
        !           243:         */
        !           244:        if (sa->sa_handler == SIG_IGN ||
        !           245:            (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
        !           246:                p->p_siglist &= ~bit;           /* never to be seen again */
        !           247:                /*
        !           248:                 *      If this is a thread signal, clean out the
        !           249:                 *      threads as well.
        !           250:                 */
        !           251:                if (bit & threadmask) {
        !           252:                        register        task_t          task = p->task;
        !           253:                        register        queue_head_t    *list;
        !           254:                        register        thread_t        thread;
        !           255: 
        !           256:                        list = &(task->thread_list);
        !           257:                        task_lock(task);
        !           258:                        thread = (thread_t) queue_first(list);
        !           259:                        while (!queue_end(list, (queue_entry_t) thread)) {
        !           260:                                thread->_uthread->uu_sig &= ~bit;
        !           261:                                thread = (thread_t)
        !           262:                                        queue_next(&thread->thread_list);
        !           263:                        }
        !           264:                        task_unlock(task);
        !           265:                }
        !           266:                if (signum != SIGCONT)
        !           267:                        p->p_sigignore |= bit;  /* easier in psignal */
        !           268:                p->p_sigcatch &= ~bit;
        !           269:        } else {
        !           270:                p->p_sigignore &= ~bit;
        !           271:                if (sa->sa_handler == SIG_DFL)
        !           272:                        p->p_sigcatch &= ~bit;
        !           273:                else
        !           274:                        p->p_sigcatch |= bit;
        !           275:        }
        !           276:        simple_unlock(&p->siglock);
        !           277:        (void) spl0();
        !           278: }
        !           279: 
        !           280: /*
        !           281:  * Initialize signal state for process 0;
        !           282:  * set to ignore signals that are ignored by default.
        !           283:  */
        !           284: void
        !           285: siginit(p)
        !           286:        struct proc *p;
        !           287: {
        !           288:        register int i;
        !           289: 
        !           290:        for (i = 0; i < NSIG; i++)
        !           291:                if (sigprop[i] & SA_IGNORE && i != SIGCONT)
        !           292:                        p->p_sigignore |= sigmask(i);
        !           293: }
        !           294: 
        !           295: /*
        !           296:  * Reset signals for an exec of the specified process.
        !           297:  */
        !           298: void
        !           299: execsigs(p)
        !           300:        register struct proc *p;
        !           301: {
        !           302:        register struct sigacts *ps = p->p_sigacts;
        !           303:        register int nc, mask;
        !           304: 
        !           305:        /*
        !           306:         * Reset caught signals.  Held signals remain held
        !           307:         * through p_sigmask (unless they were caught,
        !           308:         * and are now ignored by default).
        !           309:         */
        !           310:        while (p->p_sigcatch) {
        !           311:                nc = ffs((long)p->p_sigcatch);
        !           312:                mask = sigmask(nc);
        !           313:                p->p_sigcatch &= ~mask;
        !           314:                if (sigprop[nc] & SA_IGNORE) {
        !           315:                        if (nc != SIGCONT)
        !           316:                                p->p_sigignore |= mask;
        !           317:                        p->p_siglist &= ~mask;
        !           318:                }
        !           319:                ps->ps_sigact[nc] = SIG_DFL;
        !           320:        }
        !           321:        /*
        !           322:         * Reset stack state to the user stack.
        !           323:         * Clear set of signals caught on the signal stack.
        !           324:         */
        !           325:        ps->ps_sigstk.ss_flags = SA_DISABLE;
        !           326:        ps->ps_sigstk.ss_size = 0;
        !           327:        ps->ps_sigstk.ss_sp = 0;
        !           328:        ps->ps_flags = 0;
        !           329: }
        !           330: 
        !           331: /*
        !           332:  * Manipulate signal mask.
        !           333:  * Note that we receive new mask, not pointer,
        !           334:  * and return old mask as return value;
        !           335:  * the library stub does the rest.
        !           336:  */
        !           337: struct sigprocmask_args {
        !           338:        int     how;
        !           339:        sigset_t mask;
        !           340: };
        !           341: int
        !           342: sigprocmask(p, uap, retval)
        !           343:        register struct proc *p;
        !           344:        struct sigprocmask_args *uap;
        !           345:        register_t *retval;
        !           346: {
        !           347:        int error = 0;
        !           348: 
        !           349:        *retval = p->p_sigmask;
        !           350:        (void) splhigh();
        !           351: 
        !           352:        switch (uap->how) {
        !           353:        case SIG_BLOCK:
        !           354:                p->p_sigmask |= uap->mask &~ sigcantmask;
        !           355:                break;
        !           356: 
        !           357:        case SIG_UNBLOCK:
        !           358:                p->p_sigmask &= ~(uap->mask);
        !           359:                break;
        !           360: 
        !           361:        case SIG_SETMASK:
        !           362:                p->p_sigmask = uap->mask &~ sigcantmask;
        !           363:                break;
        !           364:        
        !           365:        default:
        !           366:                error = EINVAL;
        !           367:                break;
        !           368:        }
        !           369:        (void) spl0();
        !           370:        return (error);
        !           371: }
        !           372: 
        !           373: /* ARGSUSED */
        !           374: int
        !           375: sigpending(p, uap, retval)
        !           376:        struct proc *p;
        !           377:        void *uap;
        !           378:        register_t *retval;
        !           379: {
        !           380: 
        !           381:        *retval = p->p_siglist;
        !           382:        return (0);
        !           383: }
        !           384: 
        !           385: #if COMPAT_43
        !           386: /*
        !           387:  * Generalized interface signal handler, 4.3-compatible.
        !           388:  */
        !           389: struct osigvec_args {
        !           390:        int signum;
        !           391:        struct sigvec *nsv;
        !           392:        struct sigvec *osv;
        !           393: };
        !           394: /* ARGSUSED */
        !           395: int
        !           396: osigvec(p, uap, retval)
        !           397:        struct proc *p;
        !           398:        register struct osigvec_args *uap;
        !           399:        register_t *retval;
        !           400: {
        !           401:        struct sigvec vec;
        !           402:        register struct sigacts *ps = p->p_sigacts;
        !           403:        register struct sigvec *sv;
        !           404:        register int signum;
        !           405:        int bit, error;
        !           406: 
        !           407:        signum = uap->signum;
        !           408:        if (signum <= 0 || signum >= NSIG ||
        !           409:            signum == SIGKILL || signum == SIGSTOP)
        !           410:                return (EINVAL);
        !           411:        sv = &vec;
        !           412:        if (uap->osv) {
        !           413:                *(sig_t *)&sv->sv_handler = ps->ps_sigact[signum];
        !           414:                sv->sv_mask = ps->ps_catchmask[signum];
        !           415:                bit = sigmask(signum);
        !           416:                sv->sv_flags = 0;
        !           417:                if ((ps->ps_sigonstack & bit) != 0)
        !           418:                        sv->sv_flags |= SV_ONSTACK;
        !           419:                if ((ps->ps_sigintr & bit) != 0)
        !           420:                        sv->sv_flags |= SV_INTERRUPT;
        !           421:                        if (p->p_flag & P_NOCLDSTOP)
        !           422:                                sv->sv_flags |= SA_NOCLDSTOP;
        !           423:                if (error = copyout((caddr_t)sv, (caddr_t)uap->osv,
        !           424:                    sizeof (vec)))
        !           425:                        return (error);
        !           426:        }
        !           427:        if (uap->nsv) {
        !           428:                if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv,
        !           429:                    sizeof (vec)))
        !           430:                        return (error);
        !           431:                sv->sv_flags ^= SA_RESTART;     /* opposite of SV_INTERRUPT */
        !           432:                setsigvec(p, signum, (struct sigaction *)sv);
        !           433:        }
        !           434:        return (0);
        !           435: }
        !           436: 
        !           437: struct osigblock_args {
        !           438:        int mask;
        !           439: };
        !           440: int
        !           441: osigblock(p, uap, retval)
        !           442:        register struct proc *p;
        !           443:        struct osigblock_args *uap;
        !           444:        register_t *retval;
        !           445: {
        !           446: 
        !           447:        (void) splhigh();
        !           448:        *retval = p->p_sigmask;
        !           449:        p->p_sigmask |= uap->mask &~ sigcantmask;
        !           450:        (void) spl0();
        !           451:        return (0);
        !           452: }
        !           453: 
        !           454: struct osigsetmask_args {
        !           455:        int mask;
        !           456: };
        !           457: int
        !           458: osigsetmask(p, uap, retval)
        !           459:        struct proc *p;
        !           460:        struct osigsetmask_args *uap;
        !           461:        register_t *retval;
        !           462: {
        !           463: 
        !           464:        (void) splhigh();
        !           465:        *retval = p->p_sigmask;
        !           466:        p->p_sigmask = uap->mask &~ sigcantmask;
        !           467:        (void) spl0();
        !           468:        return (0);
        !           469: }
        !           470: #endif /* COMPAT_43 */
        !           471: 
        !           472: /*
        !           473:  * Suspend process until signal, providing mask to be set
        !           474:  * in the meantime.  Note nonstandard calling convention:
        !           475:  * libc stub passes mask, not pointer, to save a copyin.
        !           476:  */
        !           477: struct sigsuspend_args {
        !           478:        int mask;
        !           479: };
        !           480: /* ARGSUSED */
        !           481: int
        !           482: sigsuspend(p, uap, retval)
        !           483:        register struct proc *p;
        !           484:        struct sigsuspend_args *uap;
        !           485:        register_t *retval;
        !           486: {
        !           487:        register struct sigacts *ps = p->p_sigacts;
        !           488: 
        !           489:        /*
        !           490:         * When returning from sigpause, we want
        !           491:         * the old mask to be restored after the
        !           492:         * signal handler has finished.  Thus, we
        !           493:         * save it here and mark the sigacts structure
        !           494:         * to indicate this.
        !           495:         */
        !           496:        ps->ps_oldmask = p->p_sigmask;
        !           497:        ps->ps_flags |= SAS_OLDMASK;
        !           498:        p->p_sigmask = uap->mask &~ sigcantmask;
        !           499:        (void) tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0);
        !           500:        /* always return EINTR rather than ERESTART... */
        !           501:        return (EINTR);
        !           502: }
        !           503: 
        !           504: #if COMPAT_43
        !           505: struct osigstack_args {
        !           506:        struct sigstack *nss;
        !           507:        struct sigstack *oss;
        !           508: };
        !           509: /* ARGSUSED */
        !           510: int
        !           511: osigstack(p, uap, retval)
        !           512:        struct proc *p;
        !           513:        register struct osigstack_args *uap;
        !           514:        register_t *retval;
        !           515: {
        !           516:        struct sigstack ss;
        !           517:        struct sigacts *psp;
        !           518:        int error = 0;
        !           519: 
        !           520:        psp = p->p_sigacts;
        !           521:        ss.ss_sp = psp->ps_sigstk.ss_sp;
        !           522:        ss.ss_onstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
        !           523:        if (uap->oss && (error = copyout((caddr_t)&ss,
        !           524:            (caddr_t)uap->oss, sizeof (struct sigstack))))
        !           525:                return (error);
        !           526:        if (uap->nss && (error = copyin((caddr_t)uap->nss,
        !           527:            (caddr_t)&ss, sizeof (ss))) == 0) {
        !           528:                psp->ps_sigstk.ss_sp = ss.ss_sp;
        !           529:                psp->ps_sigstk.ss_size = 0;
        !           530:                psp->ps_sigstk.ss_flags |= ss.ss_onstack & SA_ONSTACK;
        !           531:                psp->ps_flags |= SAS_ALTSTACK;
        !           532:        }
        !           533:        return (error);
        !           534: }
        !           535: #endif /* COMPAT_43 */
        !           536: 
        !           537: struct sigaltstack_args {
        !           538:        struct sigaltstack *nss;
        !           539:        struct sigaltstack *oss;
        !           540: };
        !           541: /* ARGSUSED */
        !           542: int
        !           543: sigaltstack(p, uap, retval)
        !           544:        struct proc *p;
        !           545:        register struct sigaltstack_args *uap;
        !           546:        register_t *retval;
        !           547: {
        !           548:        struct sigacts *psp;
        !           549:        struct sigaltstack ss;
        !           550:        int error;
        !           551: 
        !           552:        psp = p->p_sigacts;
        !           553:        if ((psp->ps_flags & SAS_ALTSTACK) == 0)
        !           554:                psp->ps_sigstk.ss_flags |= SA_DISABLE;
        !           555:        if (uap->oss && (error = copyout((caddr_t)&psp->ps_sigstk,
        !           556:            (caddr_t)uap->oss, sizeof (struct sigaltstack))))
        !           557:                return (error);
        !           558:        if (uap->nss == 0)
        !           559:                return (0);
        !           560:        if (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
        !           561:            sizeof (ss)))
        !           562:                return (error);
        !           563:        if (ss.ss_flags & SA_DISABLE) {
        !           564:                if (psp->ps_sigstk.ss_flags & SA_ONSTACK)
        !           565:                        return (EINVAL);
        !           566:                psp->ps_flags &= ~SAS_ALTSTACK;
        !           567:                psp->ps_sigstk.ss_flags = ss.ss_flags;
        !           568:                return (0);
        !           569:        }
        !           570:        if (ss.ss_size < MINSIGSTKSZ)
        !           571:                return (ENOMEM);
        !           572:        psp->ps_flags |= SAS_ALTSTACK;
        !           573:        psp->ps_sigstk= ss;
        !           574:        return (0);
        !           575: }
        !           576: 
        !           577: struct kill_args {
        !           578:        int pid;
        !           579:        int signum;
        !           580: };
        !           581: /* ARGSUSED */
        !           582: int
        !           583: kill(cp, uap, retval)
        !           584:        register struct proc *cp;
        !           585:        register struct kill_args *uap;
        !           586:        register_t *retval;
        !           587: {
        !           588:        register struct proc *p;
        !           589:        register struct pcred *pc = cp->p_cred;
        !           590: 
        !           591:        if ((u_int)uap->signum >= NSIG)
        !           592:                return (EINVAL);
        !           593:        if (uap->pid > 0) {
        !           594:                /* kill single process */
        !           595:                if ((p = pfind(uap->pid)) == NULL)
        !           596:                        return (ESRCH);
        !           597:                if (!cansignal(cp, pc, p, uap->signum))
        !           598:                        return (EPERM);
        !           599:                if (uap->signum)
        !           600:                        psignal(p, uap->signum);
        !           601:                return (0);
        !           602:        }
        !           603:        switch (uap->pid) {
        !           604:        case -1:                /* broadcast signal */
        !           605:                return (killpg1(cp, uap->signum, 0, 1));
        !           606:        case 0:                 /* signal own process group */
        !           607:                return (killpg1(cp, uap->signum, 0, 0));
        !           608:        default:                /* negative explicit process group */
        !           609:                return (killpg1(cp, uap->signum, -(uap->pid), 0));
        !           610:        }
        !           611:        /* NOTREACHED */
        !           612: }
        !           613: 
        !           614: #if COMPAT_43
        !           615: struct okillpg_args {
        !           616:        int pgid;
        !           617:        int signum;
        !           618: };
        !           619: /* ARGSUSED */
        !           620: int
        !           621: okillpg(p, uap, retval)
        !           622:        struct proc *p;
        !           623:        register struct okillpg_args *uap;
        !           624:        register_t *retval;
        !           625: {
        !           626: 
        !           627:        if ((u_int)uap->signum >= NSIG)
        !           628:                return (EINVAL);
        !           629:        return (killpg1(p, uap->signum, uap->pgid, 0));
        !           630: }
        !           631: #endif /* COMPAT_43 */
        !           632: 
        !           633: /*
        !           634:  * Common code for kill process group/broadcast kill.
        !           635:  * cp is calling process.
        !           636:  */
        !           637: int
        !           638: killpg1(cp, signum, pgid, all)
        !           639:        register struct proc *cp;
        !           640:        int signum, pgid, all;
        !           641: {
        !           642:        register struct proc *p;
        !           643:        register struct pcred *pc = cp->p_cred;
        !           644:        struct pgrp *pgrp;
        !           645:        int nfound = 0;
        !           646:        
        !           647:        if (all)        
        !           648:                /* 
        !           649:                 * broadcast 
        !           650:                 */
        !           651:                for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
        !           652:                        if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || 
        !           653:                            p == cp || !cansignal(cp, pc, p, signum))
        !           654:                                continue;
        !           655:                        nfound++;
        !           656:                        if (signum)
        !           657:                                psignal(p, signum);
        !           658:                }
        !           659:        else {
        !           660:                if (pgid == 0)          
        !           661:                        /* 
        !           662:                         * zero pgid means send to my process group.
        !           663:                         */
        !           664:                        pgrp = cp->p_pgrp;
        !           665:                else {
        !           666:                        pgrp = pgfind(pgid);
        !           667:                        if (pgrp == NULL)
        !           668:                                return (ESRCH);
        !           669:                }
        !           670:                for (p = pgrp->pg_members.lh_first; p != 0;
        !           671:                     p = p->p_pglist.le_next) {
        !           672:                        if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
        !           673:                            p->p_stat == SZOMB ||
        !           674:                            !cansignal(cp, pc, p, signum))
        !           675:                                continue;
        !           676:                        nfound++;
        !           677:                        if (signum)
        !           678:                                psignal(p, signum);
        !           679:                }
        !           680:        }
        !           681:        return (nfound ? 0 : ESRCH);
        !           682: }
        !           683: 
        !           684: /*
        !           685:  * Send a signal to a process group.
        !           686:  */
        !           687: void
        !           688: gsignal(pgid, signum)
        !           689:        int pgid, signum;
        !           690: {
        !           691:        struct pgrp *pgrp;
        !           692: 
        !           693:        if (pgid && (pgrp = pgfind(pgid)))
        !           694:                pgsignal(pgrp, signum, 0);
        !           695: }
        !           696: 
        !           697: /*
        !           698:  * Send a signal to a process group.  If checktty is 1,
        !           699:  * limit to members which have a controlling terminal.
        !           700:  */
        !           701: void
        !           702: pgsignal(pgrp, signum, checkctty)
        !           703:        struct pgrp *pgrp;
        !           704:        int signum, checkctty;
        !           705: {
        !           706:        register struct proc *p;
        !           707: 
        !           708:        if (pgrp)
        !           709:                for (p = pgrp->pg_members.lh_first; p != 0;
        !           710:                     p = p->p_pglist.le_next)
        !           711:                        if (checkctty == 0 || p->p_flag & P_CONTROLT)
        !           712:                                psignal(p, signum);
        !           713: }
        !           714: 
        !           715: /*
        !           716:  * Send a signal caused by a trap to a specific thread.
        !           717:  */
        !           718: void
        !           719: threadsignal(thread, signum, code)
        !           720:        struct thread *thread;
        !           721:        register int signum;
        !           722:        u_long code;
        !           723: {
        !           724:        register struct uthread *uth = thread->_uthread;
        !           725:        register struct proc *p = thread->task->proc;
        !           726:        int mask;
        !           727: 
        !           728:        if ((u_int)signum >= NSIG || signum == 0)
        !           729:                return;
        !           730: 
        !           731:        mask = sigmask(signum);
        !           732:        if ((mask & threadmask) == 0)
        !           733:                return;
        !           734: 
        !           735:        if (!(p->p_flag & P_TRACED) && (p->p_sigignore & mask))
        !           736:                return;
        !           737: 
        !           738:        simple_lock(&p->siglock);
        !           739:        uth->uu_sig |= mask;
        !           740:        uth->uu_code = code;
        !           741:        simple_unlock(&p->siglock);
        !           742: }
        !           743: 
        !           744: /*
        !           745:  * Send the signal to the process.  If the signal has an action, the action
        !           746:  * is usually performed by the target process rather than the caller; we add
        !           747:  * the signal to the set of pending signals for the process.
        !           748:  *
        !           749:  * Exceptions:
        !           750:  *   o When a stop signal is sent to a sleeping process that takes the
        !           751:  *     default action, the process is stopped without awakening it.
        !           752:  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
        !           753:  *     regardless of the signal action (eg, blocked or ignored).
        !           754:  *
        !           755:  * Other ignored signals are discarded immediately.
        !           756:  */
        !           757: void
        !           758: psignal(p, signum)
        !           759:        register struct proc *p;
        !           760:        register int signum;
        !           761: {
        !           762:        register int s, prop;
        !           763:        register sig_t action;
        !           764:        register thread_t       sig_thread;
        !           765:        register task_t         sig_task;
        !           766:        register thread_t       cur_thread;
        !           767:        int mask;
        !           768: 
        !           769:        if ((u_int)signum >= NSIG || signum == 0)
        !           770:                panic("psignal signal number");
        !           771:        mask = sigmask(signum);
        !           772:        prop = sigprop[signum];
        !           773: 
        !           774:        /*
        !           775:         *      We will need the task pointer later.  Grab it now to
        !           776:         *      check for a zombie process.  Also don't send signals
        !           777:         *      to kernel internal tasks.
        !           778:         */
        !           779:        if (((sig_task = p->task) == TASK_NULL) || sig_task->kernel_vm_space)
        !           780:                return;
        !           781: 
        !           782:        /*
        !           783:         * If proc is traced, always give parent a chance.
        !           784:         */
        !           785:        if (p->p_flag & P_TRACED)
        !           786:                action = SIG_DFL;
        !           787:        else {
        !           788:                /*
        !           789:                 * If the signal is being ignored,
        !           790:                 * then we forget about it immediately.
        !           791:                 * (Note: we don't set SIGCONT in p_sigignore,
        !           792:                 * and if it is set to SIG_IGN,
        !           793:                 * action will be SIG_DFL here.)
        !           794:                 */
        !           795:                if (p->p_sigignore & mask)
        !           796:                        return;
        !           797:                if (p->p_sigmask & mask)
        !           798:                        action = SIG_HOLD;
        !           799:                else if (p->p_sigcatch & mask)
        !           800:                        action = SIG_CATCH;
        !           801:                else
        !           802:                        action = SIG_DFL;
        !           803:        }
        !           804: 
        !           805:        if (p->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) &&
        !           806:                (p->p_flag & P_TRACED) == 0)
        !           807:                p->p_nice = NZERO;
        !           808: 
        !           809:        if (prop & SA_CONT)
        !           810:                p->p_siglist &= ~stopsigmask;
        !           811: 
        !           812:        if (prop & SA_STOP) {
        !           813:                /*
        !           814:                 * If sending a tty stop signal to a member of an orphaned
        !           815:                 * process group, discard the signal here if the action
        !           816:                 * is default; don't stop the process below if sleeping,
        !           817:                 * and don't clear any pending SIGCONT.
        !           818:                 */
        !           819:                if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 &&
        !           820:                        action == SIG_DFL)
        !           821:                        return;
        !           822:                p->p_siglist &= ~contsigmask;
        !           823:        }
        !           824:        p->p_siglist |= mask;
        !           825: 
        !           826:        /*
        !           827:         * Defer further processing for signals which are held,
        !           828:         * except that stopped processes must be continued by SIGCONT.
        !           829:         */
        !           830:        if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP))
        !           831:                return;
        !           832:                
        !           833:        /*
        !           834:         *      Deliver the signal to the first thread in the task. This
        !           835:         *      allows single threaded applications which use signals to
        !           836:         *      be able to be linked with multithreaded libraries.  We have
        !           837:         *      an implicit reference to the current_thread, but need
        !           838:         *      an explicit one otherwise.  The thread reference keeps
        !           839:         *      the corresponding task data structures around too.  This
        !           840:         *      reference is released by thread_deallocate_interrupt
        !           841:         *      because psignal() can be called from interrupt level).
        !           842:         */
        !           843:        
        !           844:        s = splhigh();
        !           845:        
        !           846:        cur_thread = current_thread();
        !           847:        
        !           848:        /*
        !           849:         *      This is a mess.  The thread_list_lock is a special
        !           850:         *      lock that excludes insert and delete operations
        !           851:         *      on the task's thread list for our benefit (can't
        !           852:         *      grab task lock because we might be at interrupt
        !           853:         *      level).  Check if there are any threads in the
        !           854:         *      task.  If there aren't, sending it a signal
        !           855:         *      isn't going to work very well, so just return.
        !           856:         */
        !           857:        simple_lock(&sig_task->thread_list_lock);
        !           858:        if (queue_empty(&sig_task->thread_list)) {
        !           859:                simple_unlock(&sig_task->thread_list_lock);
        !           860:                (void) splx(s);
        !           861:                return;
        !           862:        }
        !           863:        sig_thread = (thread_t) queue_first(&sig_task->thread_list);
        !           864:        if (sig_thread != cur_thread)
        !           865:                thread_reference(sig_thread);
        !           866:        simple_unlock(&sig_task->thread_list_lock);
        !           867: 
        !           868:        /*
        !           869:         *      SIGKILL priority twiddling moved here from above because
        !           870:         *      it needs sig_thread.  Could merge it into large switch
        !           871:         *      below if we didn't care about priority for tracing
        !           872:         *      as SIGKILL's action is always SIG_DFL.
        !           873:         */
        !           874:        if ((signum == SIGKILL) && (p->p_nice > NZERO)) {
        !           875:                p->p_nice = NZERO;
        !           876:                thread_max_priority(sig_thread, sig_thread->processor_set,
        !           877:                        BASEPRI_USER);
        !           878:                thread_priority(sig_thread, BASEPRI_USER, FALSE);
        !           879:        }
        !           880: 
        !           881:        /*
        !           882:         *      Process is traced - wake it up (if not already
        !           883:         *      stopped) so that it can discover the signal in
        !           884:         *      issig() and stop for the parent.
        !           885:         */
        !           886:        if (p->p_flag & P_TRACED) {
        !           887:                if (p->p_stat != SSTOP)
        !           888:                        goto run;
        !           889:                else
        !           890:                        goto out;
        !           891:        }
        !           892: 
        !           893:        if (action != SIG_DFL) {
        !           894:                /*
        !           895:                 *      User wants to catch the signal.
        !           896:                 *      Wake up the thread, but don't un-suspend it
        !           897:                 *      (except for SIGCONT).
        !           898:                 */
        !           899:                if (prop & SA_CONT)
        !           900:                        (void) task_resume(sig_task);
        !           901:                goto run;
        !           902:        } else {
        !           903:                /*      Default action - varies */
        !           904: 
        !           905:                if (mask & stopsigmask) {
        !           906:                        /*
        !           907:                         * These are the signals which by default
        !           908:                         * stop a process.
        !           909:                         *
        !           910:                         * Don't clog system with children of init
        !           911:                         * stopped from the keyboard.
        !           912:                         */
        !           913:                        if (!(prop & SA_STOP) && p->p_pptr == initproc) {
        !           914:                                psignal(p, SIGKILL);
        !           915:                                p->p_siglist &= ~mask;
        !           916:                                goto out;
        !           917:                        }
        !           918:                        /*
        !           919:                         *      Stop the task.
        !           920:                         */
        !           921:                        if ((sig_thread->state & TH_RUN) == 0) {
        !           922:                                /*
        !           923:                                 *      If task hasn't already been stopped by
        !           924:                                 *      a signal, stop it.
        !           925:                                 */
        !           926:                                p->p_siglist &= ~mask;
        !           927:                                if (sig_task->user_stop_count == 0) {
        !           928:                                        /*
        !           929:                                         * p_cursig must not be set, because
        !           930:                                         * it will be psig()'d if it is not
        !           931:                                         * zero, and the signal is being
        !           932:                                         * handled here.  But save the signal
        !           933:                                         * in p_stopsig so WUNTRACED
        !           934:                                         * option to wait can find it.
        !           935:                                         */
        !           936:                                        p->p_xstat = signum;
        !           937:                                        if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
        !           938:                                                psignal(p->p_pptr, SIGCHLD);
        !           939:                                        stop(p);
        !           940:                                }
        !           941:                                goto out;
        !           942:                        }
        !           943:                        else {
        !           944:                                if ((p == current_proc()) && (p->p_stat != SZOMB))
        !           945:                                        ast_on(cpu_number(), AST_UNIX);
        !           946:                                goto out;
        !           947:                        }
        !           948:                }
        !           949: 
        !           950:                switch (signum) {
        !           951:                        /*
        !           952:                         * Signals ignored by default have been dealt
        !           953:                         * with already, since their bits are on in
        !           954:                         * p_sigignore.
        !           955:                         */
        !           956: 
        !           957:                case SIGKILL:
        !           958:                        /*
        !           959:                         * Kill signal always sets process running and
        !           960:                         * unsuspends it.
        !           961:                         */
        !           962:                        while (sig_task->user_stop_count > 0)
        !           963:                                (void) task_resume(sig_task);
        !           964:                        /*
        !           965:                         *      Process will be running after 'run'
        !           966:                         */
        !           967:                        p->p_stat = SRUN;
        !           968: 
        !           969:                        /*
        !           970:                         * Break it out of user wait, as well.
        !           971:                         */
        !           972:                        while (sig_thread->user_stop_count > 0)
        !           973:                                (void) thread_resume(sig_thread);
        !           974: 
        !           975:                        /*
        !           976:                         * Clear system wait if possible.  The
        !           977:                         * THREAD_SHOULD_TERMINATE is overkill, but
        !           978:                         * saves us from potentially buggy code elsewhere.
        !           979:                         */
        !           980:                        clear_wait(sig_thread, THREAD_SHOULD_TERMINATE, FALSE);
        !           981: #if    MACH_HOST
        !           982:                        /*
        !           983:                         * Make sure it can run.
        !           984:                         */
        !           985:                        if (sig_thread->processor_set->empty)
        !           986:                                thread_assign(sig_thread, &default_pset);
        !           987: #endif
        !           988:                        /*
        !           989:                         * If we're delivering the signal to some other
        !           990:                         * thread, that thread might be stuck in an
        !           991:                         * exception.  Break it out.  Can't call
        !           992:                         * thread_exception_abort from high spl, but
        !           993:                         * SIGKILL can't be sent from interrupt level, so
        !           994:                         * it's ok to drop spl.  Can call thread_deallocate
        !           995:                         * for same reason.
        !           996:                         */
        !           997:                        splx(s);
        !           998:                        if (sig_thread != cur_thread) {
        !           999:                                mach_msg_abort_rpc(sig_thread);
        !          1000:                                thread_deallocate(sig_thread);
        !          1001:                        }
        !          1002:                        return;
        !          1003: 
        !          1004:                case SIGCONT:
        !          1005:                        /*
        !          1006:                         * Let the process run.  If it's sleeping on an
        !          1007:                         * event, it remains so.
        !          1008:                         */
        !          1009:                        (void) task_resume(sig_task);
        !          1010:                        p->p_stat = SRUN;
        !          1011:                        goto out;
        !          1012: 
        !          1013:                default:
        !          1014:                        /*
        !          1015:                         * All other signals wake up the process, but don't
        !          1016:                         * resume it.
        !          1017:                         */
        !          1018:                        goto run;
        !          1019:                }
        !          1020:        }
        !          1021:        /*NOTREACHED*/
        !          1022: run:
        !          1023:        /*
        !          1024:         * If we're being traced (possibly because someone attached us
        !          1025:         * while we were stopped), check for a signal from the debugger.
        !          1026:         */
        !          1027:     if (p->p_stat == SSTOP) {
        !          1028:         if ((p->p_flag & P_TRACED) != 0 && p->p_xstat != 0)
        !          1029:             p->p_siglist |= sigmask(p->p_xstat); 
        !          1030:     }
        !          1031: 
        !          1032:        /*
        !          1033:         * setrunnable(p) in BSD
        !          1034:         */
        !          1035: 
        !          1036:        p->p_stat = SRUN;
        !          1037: 
        !          1038:        /*
        !          1039:         *      Wake up the thread if it is interruptible.
        !          1040:         */
        !          1041:        clear_wait(sig_thread, THREAD_INTERRUPTED, TRUE);
        !          1042: out:
        !          1043:        splx(s);
        !          1044:        if (sig_thread != cur_thread)
        !          1045:                thread_deallocate_interrupt(sig_thread);
        !          1046: }
        !          1047: 
        !          1048: __inline__ void
        !          1049: sig_lock_to_exit(
        !          1050:        struct proc     *p)
        !          1051: {
        !          1052:        thread_t        self = current_thread();
        !          1053: 
        !          1054:        p->exit_thread = self;
        !          1055:        simple_unlock(&p->siglock);
        !          1056:        (void) task_hold(p->task);
        !          1057:        (void) task_dowait(p->task, FALSE);
        !          1058: }
        !          1059: 
        !          1060: __inline__ int
        !          1061: sig_try_lock(
        !          1062:        struct proc     *p)
        !          1063: {
        !          1064:        thread_t        self = current_thread();
        !          1065: 
        !          1066:        simple_lock(&p->siglock);
        !          1067:        while (p->sigwait || p->exit_thread) {
        !          1068:                 simple_unlock(&p->siglock);
        !          1069:                 if (p->exit_thread) {
        !          1070:                        if (p->exit_thread == self) {
        !          1071:                                /*
        !          1072:                                 * Already exiting - no signals.
        !          1073:                                 */
        !          1074:                                return 0;
        !          1075:                        }
        !          1076:                        else {
        !          1077:                                /*
        !          1078:                                 * Another thread has called exit -
        !          1079:                                 * stop (until terminate request).
        !          1080:                                 */
        !          1081:                                thread_hold(self);
        !          1082:                        }
        !          1083:                }
        !          1084:                thread_block_with_continuation((void (*)(void)) 0);
        !          1085:                if (thread_should_halt(self)) {
        !          1086:                        /*
        !          1087:                         * Terminate request - clean up.
        !          1088:                         */
        !          1089:                        return -1;
        !          1090:                }
        !          1091:                simple_lock(&p->siglock);
        !          1092:        }
        !          1093: 
        !          1094:        return 1;
        !          1095: }
        !          1096: 
        !          1097: /*
        !          1098:  * If the current process has received a signal (should be caught or cause
        !          1099:  * termination, should interrupt current syscall), return the signal number.
        !          1100:  * Stop signals with default action are processed immediately, then cleared;
        !          1101:  * they aren't returned.  This is checked after each entry to the system for
        !          1102:  * a syscall or trap (though this can usually be done without calling issignal
        !          1103:  * by checking the pending signal masks in the CURSIG macro.) The normal call
        !          1104:  * sequence is
        !          1105:  *
        !          1106:  *     while (signum = CURSIG(curproc))
        !          1107:  *             postsig(signum);
        !          1108:  */
        !          1109: int
        !          1110: issignal(p)
        !          1111:        register struct proc *p;
        !          1112: {
        !          1113:        register int signum, mask, prop, sigbits;
        !          1114:        task_t task = p->task;
        !          1115:        thread_t initial_thread;
        !          1116:        thread_t cur_thread;
        !          1117:        int     s;
        !          1118: 
        !          1119: #if DIAGNOSTIC
        !          1120:        /*
        !          1121:         *      This must be called on master cpu
        !          1122:         */
        !          1123:        if (cpu_number() != master_cpu)
        !          1124:                panic("issig not on master");
        !          1125: #endif /* DIAGNOSTIC */
        !          1126: 
        !          1127:        /*
        !          1128:         * Try to grab the signal lock.
        !          1129:         */
        !          1130:        if (sig_try_lock(p) <= 0)
        !          1131:                return (0);
        !          1132:        
        !          1133:        /*
        !          1134:         * only allow delivery of process signals (asynchronous)
        !          1135:         * to the initial thread. This is the first thread in
        !          1136:         * the tasks thread list.
        !          1137:         */
        !          1138:        s = splsched();
        !          1139:        simple_lock(&task->thread_list_lock);
        !          1140:        initial_thread = (thread_t)queue_first(&task->thread_list);
        !          1141:        simple_unlock(&task->thread_list_lock);
        !          1142:        splx(s);
        !          1143:        cur_thread = current_thread();
        !          1144: 
        !          1145:        for(;;) {
        !          1146:                sigbits = (cur_thread->_uthread->uu_sig |p->p_siglist) & ~p->p_sigmask;
        !          1147: 
        !          1148:                for (;;) {
        !          1149:                        if (p->p_flag & P_PPWAIT)
        !          1150:                                sigbits &= ~stopsigmask;
        !          1151:                        if (sigbits == 0) {             /* no signal to send */
        !          1152:                                simple_unlock(&p->siglock);
        !          1153:                                return (0);
        !          1154:                        }
        !          1155:                        signum = ffs((long)sigbits);
        !          1156:                        mask = sigmask(signum);
        !          1157:                        prop = sigprop[signum];
        !          1158:                
        !          1159:                        if (mask & threadmask) {
        !          1160:                                /* we can take this signal */
        !          1161:                                cur_thread->_uthread->uu_sig &= ~mask;
        !          1162:                                break;
        !          1163:                        } else {
        !          1164:                                if (cur_thread != initial_thread)
        !          1165:                                        sigbits &= ~mask;
        !          1166:                                else
        !          1167:                                        break;
        !          1168:                        }
        !          1169:                }
        !          1170: 
        !          1171:                /*
        !          1172:                 * We should see pending but ignored signals
        !          1173:                 * only if P_TRACED was on when they were posted.
        !          1174:                 */
        !          1175:                if (mask & p->p_sigignore && (p->p_flag & P_TRACED) == 0) {
        !          1176:                        p->p_siglist &= ~mask;          /* take the signal! */
        !          1177:                        continue;
        !          1178:                }
        !          1179:                if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
        !          1180:                        register int    hold;
        !          1181:                        register task_t task;
        !          1182:                        /*
        !          1183:                         * If traced, always stop, and stay
        !          1184:                         * stopped until released by the debugger.
        !          1185:                         */
        !          1186: 
        !          1187:                        if (p->p_flag & P_FSTRACE) {
        !          1188: #if    PROCFS
        !          1189:                                /* procfs debugging */
        !          1190:                                p->p_stat = SSTOP;
        !          1191:                                wakeup((caddr_t)p);
        !          1192: #error need to implement 
        !          1193:                                panic("procfs debugging");
        !          1194: #endif
        !          1195:                        } else {
        !          1196:                                /* ptrace debugging */
        !          1197:                                p->p_xstat = signum;
        !          1198:                                psignal(p->p_pptr, SIGCHLD);
        !          1199:                                pcb_synch(cur_thread);
        !          1200:                                /*
        !          1201:                                 *      XXX Have to really stop for debuggers;
        !          1202:                                 *      XXX stop() doesn't do the right thing.
        !          1203:                                 *      XXX Inline the task_suspend because we
        !          1204:                                 *      XXX have to diddle Unix state in the
        !          1205:                                 *      XXX middle of it.
        !          1206:                                 */
        !          1207:                                task = p->task;
        !          1208:                                hold = FALSE;
        !          1209:                                task_lock(task);
        !          1210:                                if ((task->user_stop_count)++ == 0)
        !          1211:                                        hold = TRUE;
        !          1212:                                task_unlock(task);
        !          1213:        
        !          1214:                                if (hold) {
        !          1215:                                        (void) task_hold(task);
        !          1216:                                        thread_reference(cur_thread);
        !          1217:                                        p->sigwait = TRUE;
        !          1218:                                        p->sigwait_thread = cur_thread;
        !          1219:                                        simple_unlock(&p->siglock);
        !          1220:                                        (void) task_dowait(task, TRUE);
        !          1221:                                        thread_hold(current_thread());
        !          1222:                                }
        !          1223:                                else {
        !          1224:                                        thread_reference(cur_thread);
        !          1225:                                        p->sigwait = TRUE;
        !          1226:                                        p->sigwait_thread = cur_thread;
        !          1227:                                        simple_unlock(&p->siglock);
        !          1228:                                }
        !          1229:                                p->p_stat = SSTOP;
        !          1230:                                p->p_flag &= ~P_WAITED;
        !          1231:                                wakeup((caddr_t)p->p_pptr);
        !          1232:                                thread_block();
        !          1233:                                simple_lock(&p->siglock);
        !          1234:                                p->sigwait = FALSE;
        !          1235:                                p->sigwait_thread = NULL;
        !          1236:                                thread_deallocate(cur_thread);
        !          1237: 
        !          1238:                                /*
        !          1239:                                 *      We get here only if task
        !          1240:                                 *      is continued or killed.  Kill condition
        !          1241:                                 *      is signalled by adding NSIG to p_cursig.
        !          1242:                                 *      Pass original p_cursig as exit value in
        !          1243:                                 *      this case.
        !          1244:                                 */
        !          1245:                                if (p->p_siglist & sigmask(SIGKILL)) {
        !          1246:                                        /*
        !          1247:                                         *      Wait event may still be outstanding;
        !          1248:                                         *      clear it, since sig_lock_to_exit will
        !          1249:                                         *      wait.
        !          1250:                                         */
        !          1251:                                        clear_wait(current_thread(),
        !          1252:                                                THREAD_INTERRUPTED,
        !          1253:                                                FALSE);
        !          1254:                                        sig_lock_to_exit(p);
        !          1255:                                        /*
        !          1256:                                         * Since this thread will be resumed
        !          1257:                                         * to allow the current syscall to
        !          1258:                                         * be completed, must save u_qsave
        !          1259:                                         * before calling exit().  (Since exit()
        !          1260:                                         * calls closef() which can trash u_qsave.)
        !          1261:                                         */
        !          1262:                                        exit1(p,signum);
        !          1263:                                }
        !          1264: 
        !          1265:                                /*
        !          1266:                                 *      We may have to quit
        !          1267:                                 */
        !          1268:                                if (thread_should_halt(current_thread())) {
        !          1269:                                        simple_unlock(&p->siglock);
        !          1270:                                        return(0);
        !          1271:                                }
        !          1272: 
        !          1273:                                p->p_siglist &= ~mask;  /* clear the old signal */
        !          1274: 
        !          1275:                                /*
        !          1276:                                 * If the traced bit got turned off, go back up
        !          1277:                                 * to the top to rescan signals.  This ensures
        !          1278:                                 * that p_sig* and ps_sigact are consistent.
        !          1279:                                 */
        !          1280:                                if ((p->p_flag & P_TRACED) == 0) {
        !          1281:                                        if (mask & threadmask)
        !          1282:                                                cur_thread->_uthread->uu_sig |= mask;
        !          1283:                                        else
        !          1284:                                                p->p_siglist |= mask;
        !          1285:                                        continue;
        !          1286:                                }
        !          1287: 
        !          1288:                                /*
        !          1289:                                 * If parent wants us to take the signal,
        !          1290:                                 * then it will leave it in p->p_xstat;
        !          1291:                                 * otherwise we just look for signals again.
        !          1292:                                 */
        !          1293:                                signum = p->p_xstat;
        !          1294:                                if (signum == 0)
        !          1295:                                        continue;
        !          1296:                                /*
        !          1297:                                 * Put the new signal into p_siglist.  If the
        !          1298:                                 * signal is being masked, look for other signals.
        !          1299:                                 */
        !          1300:                                mask = sigmask(signum);
        !          1301:                                if (mask & threadmask)
        !          1302:                                        cur_thread->_uthread->uu_sig |= mask;
        !          1303:                                else
        !          1304:                                        p->p_siglist |= mask;
        !          1305:                                if (p->p_sigmask & mask)
        !          1306:                                        continue;
        !          1307:                        }
        !          1308:                }
        !          1309: 
        !          1310:                /*
        !          1311:                 * Decide whether the signal should be returned.
        !          1312:                 * Return the signal's number, or fall through
        !          1313:                 * to clear it from the pending mask.
        !          1314:                 */
        !          1315: 
        !          1316:                switch ((long)p->p_sigacts->ps_sigact[signum]) {
        !          1317:                
        !          1318:                case (long)SIG_DFL:
        !          1319:                        /*
        !          1320:                         * Don't take default actions on system processes.
        !          1321:                         */
        !          1322:                        if (p->p_pptr->p_pid == 0) {
        !          1323: #if DIAGNOSTIC
        !          1324:                                /*
        !          1325:                                 * Are you sure you want to ignore SIGSEGV
        !          1326:                                 * in init? XXX
        !          1327:                                 */
        !          1328:                                printf("Process (pid %d) got signal %d\n",
        !          1329:                                        p->p_pid, signum);
        !          1330: #endif
        !          1331:                                break;                          /* == ignore */
        !          1332:                        }
        !          1333:                        
        !          1334:                        /*
        !          1335:                         * If there is a pending stop signal to process
        !          1336:                         * with default action, stop here,
        !          1337:                         * then clear the signal.  However,
        !          1338:                         * if process is member of an orphaned
        !          1339:                         * process group, ignore tty stop signals.
        !          1340:                         */
        !          1341:                        if (prop & SA_STOP) {
        !          1342:                                if (p->p_flag & P_TRACED ||
        !          1343:                                    (p->p_pgrp->pg_jobc == 0 &&
        !          1344:                                    prop & SA_TTYSTOP))
        !          1345:                                        break;  /* == ignore */
        !          1346:                                p->p_xstat = signum;
        !          1347:                                stop(p);
        !          1348:                                if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
        !          1349:                                        psignal(p->p_pptr, SIGCHLD);
        !          1350:                                thread_reference(cur_thread);
        !          1351:                                p->sigwait = TRUE;
        !          1352:                                p->sigwait_thread = cur_thread;
        !          1353:                                simple_unlock(&p->siglock);
        !          1354:                                thread_block();
        !          1355:                                simple_lock(&p->siglock);
        !          1356:                                p->sigwait = FALSE;
        !          1357:                                p->sigwait_thread = NULL;
        !          1358:                                thread_deallocate(cur_thread);
        !          1359:                                /*
        !          1360:                                 *      We may have to quit
        !          1361:                                 */
        !          1362:                                if (thread_should_halt(current_thread())) {
        !          1363:                                        simple_unlock(&p->siglock);
        !          1364:                                        return(0);
        !          1365:                                }
        !          1366:                                break;
        !          1367:                        } else if (prop & SA_IGNORE) {
        !          1368:                                /*
        !          1369:                                 * Except for SIGCONT, shouldn't get here.
        !          1370:                                 * Default action is to ignore; drop it.
        !          1371:                                 */
        !          1372:                                break;          /* == ignore */
        !          1373:                        } else {
        !          1374:                                simple_unlock(&p->siglock);
        !          1375:                                return (signum);
        !          1376:                        }
        !          1377:                        /*NOTREACHED*/
        !          1378: 
        !          1379:                case (long)SIG_IGN:
        !          1380:                        /*
        !          1381:                         * Masking above should prevent us ever trying
        !          1382:                         * to take action on an ignored signal other
        !          1383:                         * than SIGCONT, unless process is traced.
        !          1384:                         */
        !          1385:                        if ((prop & SA_CONT) == 0 &&
        !          1386:                            (p->p_flag & P_TRACED) == 0)
        !          1387:                                printf("issignal\n");
        !          1388:                        break;          /* == ignore */
        !          1389: 
        !          1390:                default:
        !          1391:                        /*
        !          1392:                         * This signal has an action, let
        !          1393:                         * postsig() process it.
        !          1394:                         */
        !          1395:                        simple_unlock(&p->siglock);
        !          1396:                        return (signum);
        !          1397:                }
        !          1398:                p->p_siglist &= ~mask;          /* take the signal! */
        !          1399:                }
        !          1400:        /* NOTREACHED */
        !          1401: }
        !          1402: 
        !          1403: /*
        !          1404:  * Put the argument process into the stopped state and notify the parent
        !          1405:  * via wakeup.  Signals are handled elsewhere.  The process must not be
        !          1406:  * on the run queue.
        !          1407:  */
        !          1408: void
        !          1409: stop(p)
        !          1410:        register struct proc *p;
        !          1411: {
        !          1412: 
        !          1413:        /*
        !          1414:         *      Call special task_suspend routine,
        !          1415:         *      because this routine is called from interrupts
        !          1416:         *      (psignal) and cannot sleep.
        !          1417:         */
        !          1418:        (void) task_suspend_nowait(p->task);    /*XXX*/
        !          1419: 
        !          1420:        p->p_stat = SSTOP;
        !          1421:        p->p_flag &= ~P_WAITED;
        !          1422:        wakeup((caddr_t)p->p_pptr);
        !          1423: }
        !          1424: 
        !          1425: /*
        !          1426:  * Take the action for the specified signal
        !          1427:  * from the current set of pending signals.
        !          1428:  */
        !          1429: void
        !          1430: postsig(signum)
        !          1431:        register int signum;
        !          1432: {
        !          1433:        register struct proc *p = current_proc();
        !          1434:        register struct sigacts *ps = p->p_sigacts;
        !          1435:        register sig_t action;
        !          1436:        u_long code;
        !          1437:        int mask, returnmask;
        !          1438: 
        !          1439: #if DIAGNOSTIC
        !          1440:        if (signum == 0)
        !          1441:                panic("postsig");
        !          1442:        /*
        !          1443:         *      This must be called on master cpu
        !          1444:         */
        !          1445:        if (cpu_number() != master_cpu)
        !          1446:                panic("psig not on master");
        !          1447: #endif
        !          1448: 
        !          1449:        /*
        !          1450:         * Try to grab the signal lock.
        !          1451:         */
        !          1452:        if (sig_try_lock(p) <= 0)
        !          1453:                return;
        !          1454: 
        !          1455:        mask = sigmask(signum);
        !          1456:        p->p_siglist &= ~mask;
        !          1457:        action = ps->ps_sigact[signum];
        !          1458: #if KTRACE
        !          1459:        if (KTRPOINT(p, KTR_PSIG))
        !          1460:                ktrpsig(p->p_tracep,
        !          1461:                    signum, action, ps->ps_flags & SAS_OLDMASK ?
        !          1462:                    ps->ps_oldmask : p->p_sigmask, 0);
        !          1463: #endif
        !          1464:        if (action == SIG_DFL) {
        !          1465:                /*
        !          1466:                 * Default action, where the default is to kill
        !          1467:                 * the process.  (Other cases were ignored above.)
        !          1468:                 */
        !          1469:                 /* called with sig_lock() held */
        !          1470:                sigexit(p, signum);
        !          1471:                /* NOTREACHED */
        !          1472:        } else {
        !          1473:                /*
        !          1474:                 * If we get here, the signal must be caught.
        !          1475:                 */
        !          1476: #if DIAGNOSTIC
        !          1477:                if (action == SIG_IGN || (p->p_sigmask & mask))
        !          1478:                    log(LOG_WARNING,
        !          1479:                        "postsig: processing masked or ignored signal\n");
        !          1480: #endif
        !          1481:                /*
        !          1482:                 * Set the new mask value and also defer further
        !          1483:                 * occurences of this signal.
        !          1484:                 *
        !          1485:                 * Special case: user has done a sigpause.  Here the
        !          1486:                 * current mask is not of interest, but rather the
        !          1487:                 * mask from before the sigpause is what we want
        !          1488:                 * restored after the signal processing is completed.
        !          1489:                 */
        !          1490:                (void) splhigh();
        !          1491:                if (ps->ps_flags & SAS_OLDMASK) {
        !          1492:                        returnmask = ps->ps_oldmask;
        !          1493:                        ps->ps_flags &= ~SAS_OLDMASK;
        !          1494:                } else
        !          1495:                        returnmask = p->p_sigmask;
        !          1496:                p->p_sigmask |= ps->ps_catchmask[signum] | mask;
        !          1497:                if (ps->ps_sig != signum) {
        !          1498:                        code = 0;
        !          1499:                } else {
        !          1500:                        code = ps->ps_code;
        !          1501:                        ps->ps_code = 0;
        !          1502:                }
        !          1503:                simple_unlock(&p->siglock);
        !          1504:                (void) spl0();
        !          1505:                p->p_stats->p_ru.ru_nsignals++;
        !          1506:                sendsig(p, action, signum, returnmask, code);
        !          1507:        }
        !          1508: }
        !          1509: 
        !          1510: /*
        !          1511:  * Force the current process to exit with the specified signal, dumping core
        !          1512:  * if appropriate.  We bypass the normal tests for masked and caught signals,
        !          1513:  * allowing unrecoverable failures to terminate the process without changing
        !          1514:  * signal state.  Mark the accounting record with the signal termination.
        !          1515:  * If dumping core, save the signal number for the debugger.  Calls exit and
        !          1516:  * does not return.
        !          1517:  */
        !          1518: void
        !          1519: sigexit(p, signum)
        !          1520:        register struct proc *p;
        !          1521:        int signum;
        !          1522: {
        !          1523: 
        !          1524:        sig_lock_to_exit(p);
        !          1525:        p->p_acflag |= AXSIG;
        !          1526:        if (sigprop[signum] & SA_CORE) {
        !          1527:                p->p_sigacts->ps_sig = signum;
        !          1528:                if (coredump(p) == 0)
        !          1529:                        signum |= WCOREFLAG;
        !          1530:        }
        !          1531:        exit1(p, W_EXITCODE(0, signum));
        !          1532:        /* NOTREACHED */
        !          1533: }
        !          1534: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.