Annotation of Net2/kern/kern_sig.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. All advertising materials mentioning features or use of this software
        !            14:  *    must display the following acknowledgement:
        !            15:  *     This product includes software developed by the University of
        !            16:  *     California, Berkeley and its contributors.
        !            17:  * 4. Neither the name of the University nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  *
        !            33:  *     @(#)kern_sig.c  7.35 (Berkeley) 6/28/91
        !            34:  */
        !            35: 
        !            36: #define        SIGPROP         /* include signal properties table */
        !            37: #include "param.h"
        !            38: #include "signalvar.h"
        !            39: #include "resourcevar.h"
        !            40: #include "namei.h"
        !            41: #include "vnode.h"
        !            42: #include "proc.h"
        !            43: #include "systm.h"
        !            44: #include "timeb.h"
        !            45: #include "times.h"
        !            46: #include "buf.h"
        !            47: #include "seg.h"
        !            48: #include "acct.h"
        !            49: #include "file.h"
        !            50: #include "kernel.h"
        !            51: #include "wait.h"
        !            52: #include "ktrace.h"
        !            53: 
        !            54: #include "machine/cpu.h"
        !            55: 
        !            56: #include "vm/vm.h"
        !            57: #include "kinfo_proc.h"
        !            58: #include "user.h"              /* for coredump */
        !            59: 
        !            60: /*
        !            61:  * Can process p, with pcred pc, send the signal signo to process q?
        !            62:  */
        !            63: #define CANSIGNAL(p, pc, q, signo) \
        !            64:        ((pc)->pc_ucred->cr_uid == 0 || \
        !            65:            (pc)->p_ruid == (q)->p_cred->p_ruid || \
        !            66:            (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
        !            67:            (pc)->p_ruid == (q)->p_ucred->cr_uid || \
        !            68:            (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
        !            69:            ((signo) == SIGCONT && (q)->p_session == (p)->p_session))
        !            70: 
        !            71: /* ARGSUSED */
        !            72: sigaction(p, uap, retval)
        !            73:        struct proc *p;
        !            74:        register struct args {
        !            75:                int     signo;
        !            76:                struct  sigaction *nsa;
        !            77:                struct  sigaction *osa;
        !            78:        } *uap;
        !            79:        int *retval;
        !            80: {
        !            81:        struct sigaction vec;
        !            82:        register struct sigaction *sa;
        !            83:        register struct sigacts *ps = p->p_sigacts;
        !            84:        register int sig;
        !            85:        int bit, error;
        !            86: 
        !            87:        sig = uap->signo;
        !            88:        if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
        !            89:                return (EINVAL);
        !            90:        sa = &vec;
        !            91:        if (uap->osa) {
        !            92:                sa->sa_handler = ps->ps_sigact[sig];
        !            93:                sa->sa_mask = ps->ps_catchmask[sig];
        !            94:                bit = sigmask(sig);
        !            95:                sa->sa_flags = 0;
        !            96:                if ((ps->ps_sigonstack & bit) != 0)
        !            97:                        sa->sa_flags |= SA_ONSTACK;
        !            98:                if ((ps->ps_sigintr & bit) == 0)
        !            99:                        sa->sa_flags |= SA_RESTART;
        !           100:                if (p->p_flag & SNOCLDSTOP)
        !           101:                        sa->sa_flags |= SA_NOCLDSTOP;
        !           102:                if (error = copyout((caddr_t)sa, (caddr_t)uap->osa,
        !           103:                    sizeof (vec)))
        !           104:                        return (error);
        !           105:        }
        !           106:        if (uap->nsa) {
        !           107:                if (error = copyin((caddr_t)uap->nsa, (caddr_t)sa,
        !           108:                    sizeof (vec)))
        !           109:                        return (error);
        !           110:                setsigvec(p, sig, sa);
        !           111:        }
        !           112:        return (0);
        !           113: }
        !           114: 
        !           115: setsigvec(p, sig, sa)
        !           116:        register struct proc *p;
        !           117:        int sig;
        !           118:        register struct sigaction *sa;
        !           119: {
        !           120:        register struct sigacts *ps = p->p_sigacts;
        !           121:        register int bit;
        !           122: 
        !           123:        bit = sigmask(sig);
        !           124:        /*
        !           125:         * Change setting atomically.
        !           126:         */
        !           127:        (void) splhigh();
        !           128:        ps->ps_sigact[sig] = sa->sa_handler;
        !           129:        ps->ps_catchmask[sig] = sa->sa_mask &~ sigcantmask;
        !           130:        if ((sa->sa_flags & SA_RESTART) == 0)
        !           131:                ps->ps_sigintr |= bit;
        !           132:        else
        !           133:                ps->ps_sigintr &= ~bit;
        !           134:        if (sa->sa_flags & SA_ONSTACK)
        !           135:                ps->ps_sigonstack |= bit;
        !           136:        else
        !           137:                ps->ps_sigonstack &= ~bit;
        !           138:        if (sig == SIGCHLD) {
        !           139:                if (sa->sa_flags & SA_NOCLDSTOP)
        !           140:                        p->p_flag |= SNOCLDSTOP;
        !           141:                else
        !           142:                        p->p_flag &= ~SNOCLDSTOP;
        !           143:        }
        !           144:        /*
        !           145:         * Set bit in p_sigignore for signals that are set to SIG_IGN,
        !           146:         * and for signals set to SIG_DFL where the default is to ignore.
        !           147:         * However, don't put SIGCONT in p_sigignore,
        !           148:         * as we have to restart the process.
        !           149:         */
        !           150:        if (sa->sa_handler == SIG_IGN ||
        !           151:            (sigprop[sig] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
        !           152:                p->p_sig &= ~bit;               /* never to be seen again */
        !           153:                if (sig != SIGCONT)
        !           154:                        p->p_sigignore |= bit;  /* easier in psignal */
        !           155:                p->p_sigcatch &= ~bit;
        !           156:        } else {
        !           157:                p->p_sigignore &= ~bit;
        !           158:                if (sa->sa_handler == SIG_DFL)
        !           159:                        p->p_sigcatch &= ~bit;
        !           160:                else
        !           161:                        p->p_sigcatch |= bit;
        !           162:        }
        !           163:        (void) spl0();
        !           164: }
        !           165: 
        !           166: /*
        !           167:  * Initialize signal state for process 0;
        !           168:  * set to ignore signals that are ignored by default.
        !           169:  */
        !           170: void
        !           171: siginit(p)
        !           172:        struct proc *p;
        !           173: {
        !           174:        register int i;
        !           175: 
        !           176:        for (i = 0; i < NSIG; i++)
        !           177:                if (sigprop[i] & SA_IGNORE && i != SIGCONT)
        !           178:                        p->p_sigignore |= sigmask(i);
        !           179: }
        !           180: 
        !           181: /*
        !           182:  * Reset signals for an exec of the specified process.
        !           183:  */
        !           184: void
        !           185: execsigs(p)
        !           186:        register struct proc *p;
        !           187: {
        !           188:        register struct sigacts *ps = p->p_sigacts;
        !           189:        register int nc, mask;
        !           190: 
        !           191:        /*
        !           192:         * Reset caught signals.  Held signals remain held
        !           193:         * through p_sigmask (unless they were caught,
        !           194:         * and are now ignored by default).
        !           195:         */
        !           196:        while (p->p_sigcatch) {
        !           197:                nc = ffs((long)p->p_sigcatch);
        !           198:                mask = sigmask(nc);
        !           199:                p->p_sigcatch &= ~mask;
        !           200:                if (sigprop[nc] & SA_IGNORE) {
        !           201:                        if (nc != SIGCONT)
        !           202:                                p->p_sigignore |= mask;
        !           203:                        p->p_sig &= ~mask;
        !           204:                }
        !           205:                ps->ps_sigact[nc] = SIG_DFL;
        !           206:        }
        !           207:        /*
        !           208:         * Reset stack state to the user stack.
        !           209:         * Clear set of signals caught on the signal stack.
        !           210:         */
        !           211:        ps->ps_onstack = 0;
        !           212:        ps->ps_sigsp = 0;
        !           213:        ps->ps_sigonstack = 0;
        !           214: }
        !           215: 
        !           216: /*
        !           217:  * Manipulate signal mask.
        !           218:  * Note that we receive new mask, not pointer,
        !           219:  * and return old mask as return value;
        !           220:  * the library stub does the rest.
        !           221:  */
        !           222: sigprocmask(p, uap, retval)
        !           223:        register struct proc *p;
        !           224:        struct args {
        !           225:                int     how;
        !           226:                sigset_t mask;
        !           227:        } *uap;
        !           228:        int *retval;
        !           229: {
        !           230:        int error = 0;
        !           231: 
        !           232:        *retval = p->p_sigmask;
        !           233:        (void) splhigh();
        !           234: 
        !           235:        switch (uap->how) {
        !           236:        case SIG_BLOCK:
        !           237:                p->p_sigmask |= uap->mask &~ sigcantmask;
        !           238:                break;
        !           239: 
        !           240:        case SIG_UNBLOCK:
        !           241:                p->p_sigmask &= ~uap->mask;
        !           242:                break;
        !           243: 
        !           244:        case SIG_SETMASK:
        !           245:                p->p_sigmask = uap->mask &~ sigcantmask;
        !           246:                break;
        !           247:        
        !           248:        default:
        !           249:                error = EINVAL;
        !           250:                break;
        !           251:        }
        !           252:        (void) spl0();
        !           253:        return (error);
        !           254: }
        !           255: 
        !           256: /* ARGSUSED */
        !           257: sigpending(p, uap, retval)
        !           258:        struct proc *p;
        !           259:        void *uap;
        !           260:        int *retval;
        !           261: {
        !           262: 
        !           263:        *retval = p->p_sig;
        !           264:        return (0);
        !           265: }
        !           266: 
        !           267: #ifdef COMPAT_43
        !           268: /*
        !           269:  * Generalized interface signal handler, 4.3-compatible.
        !           270:  */
        !           271: /* ARGSUSED */
        !           272: osigvec(p, uap, retval)
        !           273:        struct proc *p;
        !           274:        register struct args {
        !           275:                int     signo;
        !           276:                struct  sigvec *nsv;
        !           277:                struct  sigvec *osv;
        !           278:        } *uap;
        !           279:        int *retval;
        !           280: {
        !           281:        struct sigvec vec;
        !           282:        register struct sigacts *ps = p->p_sigacts;
        !           283:        register struct sigvec *sv;
        !           284:        register int sig;
        !           285:        int bit, error;
        !           286: 
        !           287:        sig = uap->signo;
        !           288:        if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
        !           289:                return (EINVAL);
        !           290:        sv = &vec;
        !           291:        if (uap->osv) {
        !           292:                *(sig_t *)&sv->sv_handler = ps->ps_sigact[sig];
        !           293:                sv->sv_mask = ps->ps_catchmask[sig];
        !           294:                bit = sigmask(sig);
        !           295:                sv->sv_flags = 0;
        !           296:                if ((ps->ps_sigonstack & bit) != 0)
        !           297:                        sv->sv_flags |= SV_ONSTACK;
        !           298:                if ((ps->ps_sigintr & bit) != 0)
        !           299:                        sv->sv_flags |= SV_INTERRUPT;
        !           300:                if (p->p_flag & SNOCLDSTOP)
        !           301:                        sv->sv_flags |= SA_NOCLDSTOP;
        !           302:                if (error = copyout((caddr_t)sv, (caddr_t)uap->osv,
        !           303:                    sizeof (vec)))
        !           304:                        return (error);
        !           305:        }
        !           306:        if (uap->nsv) {
        !           307:                if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv,
        !           308:                    sizeof (vec)))
        !           309:                        return (error);
        !           310:                sv->sv_flags ^= SA_RESTART;     /* opposite of SV_INTERRUPT */
        !           311:                setsigvec(p, sig, (struct sigaction *)sv);
        !           312:        }
        !           313:        return (0);
        !           314: }
        !           315: 
        !           316: osigblock(p, uap, retval)
        !           317:        register struct proc *p;
        !           318:        struct args {
        !           319:                int     mask;
        !           320:        } *uap;
        !           321:        int *retval;
        !           322: {
        !           323: 
        !           324:        (void) splhigh();
        !           325:        *retval = p->p_sigmask;
        !           326:        p->p_sigmask |= uap->mask &~ sigcantmask;
        !           327:        (void) spl0();
        !           328:        return (0);
        !           329: }
        !           330: 
        !           331: osigsetmask(p, uap, retval)
        !           332:        struct proc *p;
        !           333:        struct args {
        !           334:                int     mask;
        !           335:        } *uap;
        !           336:        int *retval;
        !           337: {
        !           338: 
        !           339:        (void) splhigh();
        !           340:        *retval = p->p_sigmask;
        !           341:        p->p_sigmask = uap->mask &~ sigcantmask;
        !           342:        (void) spl0();
        !           343:        return (0);
        !           344: }
        !           345: #endif
        !           346: 
        !           347: /*
        !           348:  * Suspend process until signal, providing mask to be set
        !           349:  * in the meantime.  Note nonstandard calling convention:
        !           350:  * libc stub passes mask, not pointer, to save a copyin.
        !           351:  */
        !           352: /* ARGSUSED */
        !           353: sigsuspend(p, uap, retval)
        !           354:        register struct proc *p;
        !           355:        struct args {
        !           356:                sigset_t mask;
        !           357:        } *uap;
        !           358:        int *retval;
        !           359: {
        !           360:        register struct sigacts *ps = p->p_sigacts;
        !           361: 
        !           362:        /*
        !           363:         * When returning from sigpause, we want
        !           364:         * the old mask to be restored after the
        !           365:         * signal handler has finished.  Thus, we
        !           366:         * save it here and mark the proc structure
        !           367:         * to indicate this (should be in sigacts).
        !           368:         */
        !           369:        ps->ps_oldmask = p->p_sigmask;
        !           370:        ps->ps_flags |= SA_OLDMASK;
        !           371:        p->p_sigmask = uap->mask &~ sigcantmask;
        !           372:        (void) tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0);
        !           373:        /* always return EINTR rather than ERESTART... */
        !           374:        return (EINTR);
        !           375: }
        !           376: 
        !           377: /* ARGSUSED */
        !           378: sigstack(p, uap, retval)
        !           379:        struct proc *p;
        !           380:        register struct args {
        !           381:                struct  sigstack *nss;
        !           382:                struct  sigstack *oss;
        !           383:        } *uap;
        !           384:        int *retval;
        !           385: {
        !           386:        struct sigstack ss;
        !           387:        int error = 0;
        !           388: 
        !           389:        if (uap->oss && (error = copyout((caddr_t)&p->p_sigacts->ps_sigstack,
        !           390:            (caddr_t)uap->oss, sizeof (struct sigstack))))
        !           391:                return (error);
        !           392:        if (uap->nss && (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
        !           393:            sizeof (ss))) == 0)
        !           394:                p->p_sigacts->ps_sigstack = ss;
        !           395:        return (error);
        !           396: }
        !           397: 
        !           398: /* ARGSUSED */
        !           399: kill(cp, uap, retval)
        !           400:        register struct proc *cp;
        !           401:        register struct args {
        !           402:                int     pid;
        !           403:                int     signo;
        !           404:        } *uap;
        !           405:        int *retval;
        !           406: {
        !           407:        register struct proc *p;
        !           408:        register struct pcred *pc = cp->p_cred;
        !           409: 
        !           410:        if ((unsigned) uap->signo >= NSIG)
        !           411:                return (EINVAL);
        !           412:        if (uap->pid > 0) {
        !           413:                /* kill single process */
        !           414:                p = pfind(uap->pid);
        !           415:                if (p == 0)
        !           416:                        return (ESRCH);
        !           417:                if (!CANSIGNAL(cp, pc, p, uap->signo))
        !           418:                        return (EPERM);
        !           419:                if (uap->signo)
        !           420:                        psignal(p, uap->signo);
        !           421:                return (0);
        !           422:        }
        !           423:        switch (uap->pid) {
        !           424:        case -1:                /* broadcast signal */
        !           425:                return (killpg1(cp, uap->signo, 0, 1));
        !           426:        case 0:                 /* signal own process group */
        !           427:                return (killpg1(cp, uap->signo, 0, 0));
        !           428:        default:                /* negative explicit process group */
        !           429:                return (killpg1(cp, uap->signo, -uap->pid, 0));
        !           430:        }
        !           431:        /* NOTREACHED */
        !           432: }
        !           433: 
        !           434: #ifdef COMPAT_43
        !           435: /* ARGSUSED */
        !           436: okillpg(p, uap, retval)
        !           437:        struct proc *p;
        !           438:        register struct args {
        !           439:                int     pgid;
        !           440:                int     signo;
        !           441:        } *uap;
        !           442:        int *retval;
        !           443: {
        !           444: 
        !           445:        if ((unsigned) uap->signo >= NSIG)
        !           446:                return (EINVAL);
        !           447:        return (killpg1(p, uap->signo, uap->pgid, 0));
        !           448: }
        !           449: #endif
        !           450: 
        !           451: /*
        !           452:  * Common code for kill process group/broadcast kill.
        !           453:  * cp is calling process.
        !           454:  */
        !           455: killpg1(cp, signo, pgid, all)
        !           456:        register struct proc *cp;
        !           457:        int signo, pgid, all;
        !           458: {
        !           459:        register struct proc *p;
        !           460:        register struct pcred *pc = cp->p_cred;
        !           461:        struct pgrp *pgrp;
        !           462:        int nfound = 0;
        !           463:        
        !           464:        if (all)        
        !           465:                /* 
        !           466:                 * broadcast 
        !           467:                 */
        !           468:                for (p = allproc; p != NULL; p = p->p_nxt) {
        !           469:                        if (p->p_pid <= 1 || p->p_flag&SSYS || 
        !           470:                            p == cp || !CANSIGNAL(cp, pc, p, signo))
        !           471:                                continue;
        !           472:                        nfound++;
        !           473:                        if (signo)
        !           474:                                psignal(p, signo);
        !           475:                }
        !           476:        else {
        !           477:                if (pgid == 0)          
        !           478:                        /* 
        !           479:                         * zero pgid means send to my process group.
        !           480:                         */
        !           481:                        pgrp = cp->p_pgrp;
        !           482:                else {
        !           483:                        pgrp = pgfind(pgid);
        !           484:                        if (pgrp == NULL)
        !           485:                                return (ESRCH);
        !           486:                }
        !           487:                for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) {
        !           488:                        if (p->p_pid <= 1 || p->p_flag&SSYS ||
        !           489:                            p->p_stat == SZOMB || !CANSIGNAL(cp, pc, p, signo))
        !           490:                                continue;
        !           491:                        nfound++;
        !           492:                        if (signo)
        !           493:                                psignal(p, signo);
        !           494:                }
        !           495:        }
        !           496:        return (nfound ? 0 : ESRCH);
        !           497: }
        !           498: 
        !           499: /*
        !           500:  * Send the specified signal to
        !           501:  * all processes with 'pgid' as
        !           502:  * process group.
        !           503:  */
        !           504: void
        !           505: gsignal(pgid, sig)
        !           506:        int pgid, sig;
        !           507: {
        !           508:        struct pgrp *pgrp;
        !           509: 
        !           510:        if (pgid && (pgrp = pgfind(pgid)))
        !           511:                pgsignal(pgrp, sig, 0);
        !           512: }
        !           513: 
        !           514: /*
        !           515:  * Send sig to every member of a process group.
        !           516:  * If checktty is 1, limit to members which have a controlling
        !           517:  * terminal.
        !           518:  */
        !           519: void
        !           520: pgsignal(pgrp, sig, checkctty)
        !           521:        struct pgrp *pgrp;
        !           522:        int sig, checkctty;
        !           523: {
        !           524:        register struct proc *p;
        !           525: 
        !           526:        if (pgrp)
        !           527:                for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt)
        !           528:                        if (checkctty == 0 || p->p_flag&SCTTY)
        !           529:                                psignal(p, sig);
        !           530: }
        !           531: 
        !           532: /*
        !           533:  * Send a signal caused by a trap to the current process.
        !           534:  * If it will be caught immediately, deliver it with correct code.
        !           535:  * Otherwise, post it normally.
        !           536:  */
        !           537: void
        !           538: trapsignal(p, sig, code)
        !           539:        struct proc *p;
        !           540:        register int sig;
        !           541:        unsigned code;
        !           542: {
        !           543:        register struct sigacts *ps = p->p_sigacts;
        !           544:        int mask;
        !           545: 
        !           546:        mask = sigmask(sig);
        !           547:        if ((p->p_flag & STRC) == 0 && (p->p_sigcatch & mask) != 0 &&
        !           548:            (p->p_sigmask & mask) == 0) {
        !           549:                p->p_stats->p_ru.ru_nsignals++;
        !           550: #ifdef KTRACE
        !           551:                if (KTRPOINT(p, KTR_PSIG))
        !           552:                        ktrpsig(p->p_tracep, sig, ps->ps_sigact[sig], 
        !           553:                                p->p_sigmask, code);
        !           554: #endif
        !           555:                sendsig(ps->ps_sigact[sig], sig, p->p_sigmask, code);
        !           556:                p->p_sigmask |= ps->ps_catchmask[sig] | mask;
        !           557:        } else {
        !           558:                ps->ps_code = code;     /* XXX for core dump/debugger */
        !           559:                psignal(p, sig);
        !           560:        }
        !           561: }
        !           562: 
        !           563: /*
        !           564:  * Send the specified signal to the specified process.
        !           565:  * If the signal has an action, the action is usually performed
        !           566:  * by the target process rather than the caller; we simply add
        !           567:  * the signal to the set of pending signals for the process.
        !           568:  * Exceptions:
        !           569:  *   o When a stop signal is sent to a sleeping process that takes the default
        !           570:  *     action, the process is stopped without awakening it.
        !           571:  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
        !           572:  *     regardless of the signal action (eg, blocked or ignored).
        !           573:  * Other ignored signals are discarded immediately.
        !           574:  */
        !           575: void
        !           576: psignal(p, sig)
        !           577:        register struct proc *p;
        !           578:        register int sig;
        !           579: {
        !           580:        register int s, prop;
        !           581:        register sig_t action;
        !           582:        int mask;
        !           583: 
        !           584:        if ((unsigned)sig >= NSIG || sig == 0)
        !           585:                panic("psignal sig");
        !           586:        mask = sigmask(sig);
        !           587:        prop = sigprop[sig];
        !           588: 
        !           589:        /*
        !           590:         * If proc is traced, always give parent a chance.
        !           591:         */
        !           592:        if (p->p_flag & STRC)
        !           593:                action = SIG_DFL;
        !           594:        else {
        !           595:                /*
        !           596:                 * If the signal is being ignored,
        !           597:                 * then we forget about it immediately.
        !           598:                 * (Note: we don't set SIGCONT in p_sigignore,
        !           599:                 * and if it is set to SIG_IGN,
        !           600:                 * action will be SIG_DFL here.)
        !           601:                 */
        !           602:                if (p->p_sigignore & mask)
        !           603:                        return;
        !           604:                if (p->p_sigmask & mask)
        !           605:                        action = SIG_HOLD;
        !           606:                else if (p->p_sigcatch & mask)
        !           607:                        action = SIG_CATCH;
        !           608:                else
        !           609:                        action = SIG_DFL;
        !           610:        }
        !           611: 
        !           612:        if (p->p_nice > NZERO && (sig == SIGKILL ||
        !           613:            sig == SIGTERM && (p->p_flag&STRC || action != SIG_DFL)))
        !           614:                p->p_nice = NZERO;
        !           615: 
        !           616:        if (prop & SA_CONT)
        !           617:                p->p_sig &= ~stopsigmask;
        !           618: 
        !           619:        if (prop & SA_STOP) {
        !           620:                /*
        !           621:                 * If sending a tty stop signal to a member of an orphaned
        !           622:                 * process group, discard the signal here if the action
        !           623:                 * is default; don't stop the process below if sleeping,
        !           624:                 * and don't clear any pending SIGCONT.
        !           625:                 */
        !           626:                if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 &&
        !           627:                    action == SIG_DFL)
        !           628:                        return;
        !           629:                p->p_sig &= ~contsigmask;
        !           630:        }
        !           631:        p->p_sig |= mask;
        !           632: 
        !           633:        /*
        !           634:         * Defer further processing for signals which are held,
        !           635:         * except that stopped processes must be continued by SIGCONT.
        !           636:         */
        !           637:        if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP))
        !           638:                return;
        !           639:        s = splhigh();
        !           640:        switch (p->p_stat) {
        !           641: 
        !           642:        case SSLEEP:
        !           643:                /*
        !           644:                 * If process is sleeping uninterruptibly
        !           645:                 * we can't interrupt the sleep... the signal will
        !           646:                 * be noticed when the process returns through
        !           647:                 * trap() or syscall().
        !           648:                 */
        !           649:                if ((p->p_flag & SSINTR) == 0)
        !           650:                        goto out;
        !           651:                /*
        !           652:                 * Process is sleeping and traced... make it runnable
        !           653:                 * so it can discover the signal in issig() and stop
        !           654:                 * for the parent.
        !           655:                 */
        !           656:                if (p->p_flag&STRC)
        !           657:                        goto run;
        !           658:                /*
        !           659:                 * When a sleeping process receives a stop
        !           660:                 * signal, process immediately if possible.
        !           661:                 * All other (caught or default) signals
        !           662:                 * cause the process to run.
        !           663:                 */
        !           664:                if (prop & SA_STOP) {
        !           665:                        if (action != SIG_DFL)
        !           666:                                goto runfast;
        !           667:                        /*
        !           668:                         * If a child holding parent blocked,
        !           669:                         * stopping could cause deadlock.
        !           670:                         */
        !           671:                        if (p->p_flag&SPPWAIT)
        !           672:                                goto out;
        !           673:                        p->p_sig &= ~mask;
        !           674:                        p->p_xstat = sig;
        !           675:                        if ((p->p_pptr->p_flag & SNOCLDSTOP) == 0)
        !           676:                                psignal(p->p_pptr, SIGCHLD);
        !           677:                        stop(p);
        !           678:                        goto out;
        !           679:                } else
        !           680:                        goto runfast;
        !           681:                /*NOTREACHED*/
        !           682: 
        !           683:        case SSTOP:
        !           684:                /*
        !           685:                 * If traced process is already stopped,
        !           686:                 * then no further action is necessary.
        !           687:                 */
        !           688:                if (p->p_flag&STRC)
        !           689:                        goto out;
        !           690: 
        !           691:                /*
        !           692:                 * Kill signal always sets processes running.
        !           693:                 */
        !           694:                if (sig == SIGKILL)
        !           695:                        goto runfast;
        !           696: 
        !           697:                if (prop & SA_CONT) {
        !           698:                        /*
        !           699:                         * If SIGCONT is default (or ignored), we continue
        !           700:                         * the process but don't leave the signal in p_sig,
        !           701:                         * as it has no further action.  If SIGCONT is held,
        !           702:                         * continue the process and leave the signal in p_sig.
        !           703:                         * If the process catches SIGCONT, let it handle
        !           704:                         * the signal itself.  If it isn't waiting on
        !           705:                         * an event, then it goes back to run state.
        !           706:                         * Otherwise, process goes back to sleep state.
        !           707:                         */
        !           708:                        if (action == SIG_DFL)
        !           709:                                p->p_sig &= ~mask;
        !           710:                        if (action == SIG_CATCH)
        !           711:                                goto runfast;
        !           712:                        if (p->p_wchan == 0)
        !           713:                                goto run;
        !           714:                        p->p_stat = SSLEEP;
        !           715:                        goto out;
        !           716:                }
        !           717: 
        !           718:                if (prop & SA_STOP) {
        !           719:                        /*
        !           720:                         * Already stopped, don't need to stop again.
        !           721:                         * (If we did the shell could get confused.)
        !           722:                         */
        !           723:                        p->p_sig &= ~mask;              /* take it away */
        !           724:                        goto out;
        !           725:                }
        !           726: 
        !           727:                /*
        !           728:                 * If process is sleeping interruptibly, then
        !           729:                 * simulate a wakeup so that when it is continued,
        !           730:                 * it will be made runnable and can look at the signal.
        !           731:                 * But don't setrun the process, leave it stopped.
        !           732:                 */
        !           733:                if (p->p_wchan && p->p_flag & SSINTR)
        !           734:                        unsleep(p);
        !           735:                goto out;
        !           736: 
        !           737:        default:
        !           738:                /*
        !           739:                 * SRUN, SIDL, SZOMB do nothing with the signal,
        !           740:                 * other than kicking ourselves if we are running.
        !           741:                 * It will either never be noticed, or noticed very soon.
        !           742:                 */
        !           743:                if (p == curproc)
        !           744:                        signotify(p);
        !           745:                goto out;
        !           746:        }
        !           747:        /*NOTREACHED*/
        !           748: 
        !           749: runfast:
        !           750:        /*
        !           751:         * Raise priority to at least PUSER.
        !           752:         */
        !           753:        if (p->p_pri > PUSER)
        !           754:                p->p_pri = PUSER;
        !           755: run:
        !           756:        setrun(p);
        !           757: out:
        !           758:        splx(s);
        !           759: }
        !           760: 
        !           761: /*
        !           762:  * If the current process has a signal to process (should be caught
        !           763:  * or cause termination, should interrupt current syscall),
        !           764:  * return the signal number.  Stop signals with default action
        !           765:  * are processed immediately, then cleared; they aren't returned.
        !           766:  * This is checked after each entry to the system for a syscall
        !           767:  * or trap (though this can usually be done without actually calling
        !           768:  * issig by checking the pending signal masks in the CURSIG macro.)
        !           769:  * The normal call sequence is
        !           770:  *
        !           771:  *     while (sig = CURSIG(curproc))
        !           772:  *             psig(sig);
        !           773:  */
        !           774: issig(p)
        !           775:        register struct proc *p;
        !           776: {
        !           777:        register int sig, mask, prop;
        !           778: 
        !           779:        for (;;) {
        !           780:                mask = p->p_sig &~ p->p_sigmask;
        !           781:                if (p->p_flag&SPPWAIT)
        !           782:                        mask &= ~stopsigmask;
        !           783:                if (mask == 0)          /* no signal to send */
        !           784:                        return (0);
        !           785:                sig = ffs((long)mask);
        !           786:                mask = sigmask(sig);
        !           787:                prop = sigprop[sig];
        !           788:                /*
        !           789:                 * We should see pending but ignored signals
        !           790:                 * only if STRC was on when they were posted.
        !           791:                 */
        !           792:                if (mask & p->p_sigignore && (p->p_flag&STRC) == 0) {
        !           793:                        p->p_sig &= ~mask;
        !           794:                        continue;
        !           795:                }
        !           796:                if (p->p_flag&STRC && (p->p_flag&SPPWAIT) == 0) {
        !           797:                        /*
        !           798:                         * If traced, always stop, and stay
        !           799:                         * stopped until released by the parent.
        !           800:                         */
        !           801:                        p->p_xstat = sig;
        !           802:                        psignal(p->p_pptr, SIGCHLD);
        !           803:                        do {
        !           804:                                stop(p);
        !           805:                                swtch();
        !           806:                        } while (!procxmt(p) && p->p_flag&STRC);
        !           807: 
        !           808:                        /*
        !           809:                         * If the traced bit got turned off,
        !           810:                         * go back up to the top to rescan signals.
        !           811:                         * This ensures that p_sig* and ps_sigact
        !           812:                         * are consistent.
        !           813:                         */
        !           814:                        if ((p->p_flag&STRC) == 0)
        !           815:                                continue;
        !           816: 
        !           817:                        /*
        !           818:                         * If parent wants us to take the signal,
        !           819:                         * then it will leave it in p->p_xstat;
        !           820:                         * otherwise we just look for signals again.
        !           821:                         */
        !           822:                        p->p_sig &= ~mask;      /* clear the old signal */
        !           823:                        sig = p->p_xstat;
        !           824:                        if (sig == 0)
        !           825:                                continue;
        !           826: 
        !           827:                        /*
        !           828:                         * Put the new signal into p_sig.
        !           829:                         * If signal is being masked,
        !           830:                         * look for other signals.
        !           831:                         */
        !           832:                        mask = sigmask(sig);
        !           833:                        p->p_sig |= mask;
        !           834:                        if (p->p_sigmask & mask)
        !           835:                                continue;
        !           836:                }
        !           837: 
        !           838:                /*
        !           839:                 * Decide whether the signal should be returned.
        !           840:                 * Return the signal's number, or fall through
        !           841:                 * to clear it from the pending mask.
        !           842:                 */
        !           843:                switch ((int)p->p_sigacts->ps_sigact[sig]) {
        !           844: 
        !           845:                case SIG_DFL:
        !           846:                        /*
        !           847:                         * Don't take default actions on system processes.
        !           848:                         */
        !           849:                        if (p->p_pid <= 1)
        !           850:                                break;          /* == ignore */
        !           851:                        /*
        !           852:                         * If there is a pending stop signal to process
        !           853:                         * with default action, stop here,
        !           854:                         * then clear the signal.  However,
        !           855:                         * if process is member of an orphaned
        !           856:                         * process group, ignore tty stop signals.
        !           857:                         */
        !           858:                        if (prop & SA_STOP) {
        !           859:                                if (p->p_flag&STRC ||
        !           860:                                    (p->p_pgrp->pg_jobc == 0 &&
        !           861:                                    prop & SA_TTYSTOP))
        !           862:                                        break;  /* == ignore */
        !           863:                                p->p_xstat = sig;
        !           864:                                stop(p);
        !           865:                                if ((p->p_pptr->p_flag & SNOCLDSTOP) == 0)
        !           866:                                        psignal(p->p_pptr, SIGCHLD);
        !           867:                                swtch();
        !           868:                                break;
        !           869:                        } else if (prop & SA_IGNORE) {
        !           870:                                /*
        !           871:                                 * Except for SIGCONT, shouldn't get here.
        !           872:                                 * Default action is to ignore; drop it.
        !           873:                                 */
        !           874:                                break;          /* == ignore */
        !           875:                        } else
        !           876:                                return (sig);
        !           877:                        /*NOTREACHED*/
        !           878: 
        !           879:                case SIG_IGN:
        !           880:                        /*
        !           881:                         * Masking above should prevent us ever trying
        !           882:                         * to take action on an ignored signal other
        !           883:                         * than SIGCONT, unless process is traced.
        !           884:                         */
        !           885:                        if ((prop & SA_CONT) == 0 && (p->p_flag&STRC) == 0)
        !           886:                                printf("issig\n");
        !           887:                        break;          /* == ignore */
        !           888: 
        !           889:                default:
        !           890:                        /*
        !           891:                         * This signal has an action, let
        !           892:                         * psig process it.
        !           893:                         */
        !           894:                        return (sig);
        !           895:                }
        !           896:                p->p_sig &= ~mask;              /* take the signal! */
        !           897:        }
        !           898:        /* NOTREACHED */
        !           899: }
        !           900: 
        !           901: /*
        !           902:  * Put the argument process into the stopped
        !           903:  * state and notify the parent via wakeup.
        !           904:  * Signals are handled elsewhere.
        !           905:  * The process must not be on the run queue.
        !           906:  */
        !           907: stop(p)
        !           908:        register struct proc *p;
        !           909: {
        !           910: 
        !           911:        p->p_stat = SSTOP;
        !           912:        p->p_flag &= ~SWTED;
        !           913:        wakeup((caddr_t)p->p_pptr);
        !           914: }
        !           915: 
        !           916: /*
        !           917:  * Take the action for the specified signal
        !           918:  * from the current set of pending signals.
        !           919:  */
        !           920: void
        !           921: psig(sig)
        !           922:        register int sig;
        !           923: {
        !           924:        register struct proc *p = curproc;
        !           925:        register struct sigacts *ps = p->p_sigacts;
        !           926:        register sig_t action;
        !           927:        int mask, returnmask;
        !           928: 
        !           929: #ifdef DIAGNOSTIC
        !           930:        if (sig == 0)
        !           931:                panic("psig");
        !           932: #endif
        !           933:        mask = sigmask(sig);
        !           934:        p->p_sig &= ~mask;
        !           935:        action = ps->ps_sigact[sig];
        !           936: #ifdef KTRACE
        !           937:        if (KTRPOINT(p, KTR_PSIG))
        !           938:                ktrpsig(p->p_tracep, sig, action, ps->ps_flags & SA_OLDMASK ?
        !           939:                    ps->ps_oldmask : p->p_sigmask, 0);
        !           940: #endif
        !           941:        if (action == SIG_DFL) {
        !           942:                /*
        !           943:                 * Default action, where the default is to kill
        !           944:                 * the process.  (Other cases were ignored above.)
        !           945:                 */
        !           946:                sigexit(p, sig);
        !           947:                /* NOTREACHED */
        !           948:        } else {
        !           949:                /*
        !           950:                 * If we get here, the signal must be caught.
        !           951:                 */
        !           952: #ifdef DIAGNOSTIC
        !           953:                if (action == SIG_IGN || (p->p_sigmask & mask))
        !           954:                        panic("psig action");
        !           955: #endif
        !           956:                /*
        !           957:                 * Set the new mask value and also defer further
        !           958:                 * occurences of this signal.
        !           959:                 *
        !           960:                 * Special case: user has done a sigpause.  Here the
        !           961:                 * current mask is not of interest, but rather the
        !           962:                 * mask from before the sigpause is what we want
        !           963:                 * restored after the signal processing is completed.
        !           964:                 */
        !           965:                (void) splhigh();
        !           966:                if (ps->ps_flags & SA_OLDMASK) {
        !           967:                        returnmask = ps->ps_oldmask;
        !           968:                        ps->ps_flags &= ~SA_OLDMASK;
        !           969:                } else
        !           970:                        returnmask = p->p_sigmask;
        !           971:                p->p_sigmask |= ps->ps_catchmask[sig] | mask;
        !           972:                (void) spl0();
        !           973:                p->p_stats->p_ru.ru_nsignals++;
        !           974:                sendsig(action, sig, returnmask, 0);
        !           975:        }
        !           976: }
        !           977: 
        !           978: /*
        !           979:  * Force the current process to exit with the specified
        !           980:  * signal, dumping core if appropriate.  We bypass the normal
        !           981:  * tests for masked and caught signals, allowing unrecoverable
        !           982:  * failures to terminate the process without changing signal state.
        !           983:  * Mark the accounting record with the signal termination.
        !           984:  * If dumping core, save the signal number for the debugger.
        !           985:  * Calls exit and does not return.
        !           986:  */
        !           987: sigexit(p, sig)
        !           988:        register struct proc *p;
        !           989:        int sig;
        !           990: {
        !           991: 
        !           992:        p->p_acflag |= AXSIG;
        !           993:        if (sigprop[sig] & SA_CORE) {
        !           994:                p->p_sigacts->ps_sig = sig;
        !           995:                if (coredump(p) == 0)
        !           996:                        sig |= WCOREFLAG;
        !           997:        }
        !           998:        exit(p, W_EXITCODE(0, sig));
        !           999:        /* NOTREACHED */
        !          1000: }
        !          1001: 
        !          1002: /*
        !          1003:  * Create a core dump.
        !          1004:  * The file name is "core.progname".
        !          1005:  * Core dumps are not created if the process is setuid.
        !          1006:  */
        !          1007: coredump(p)
        !          1008:        register struct proc *p;
        !          1009: {
        !          1010:        register struct vnode *vp;
        !          1011:        register struct pcred *pcred = p->p_cred;
        !          1012:        register struct ucred *cred = pcred->pc_ucred;
        !          1013:        register struct vmspace *vm = p->p_vmspace;
        !          1014:        struct vattr vattr;
        !          1015:        int error, error1;
        !          1016:        struct nameidata nd;
        !          1017:        char name[MAXCOMLEN+6]; /* core.progname */
        !          1018: 
        !          1019:        if (pcred->p_svuid != pcred->p_ruid ||
        !          1020:            pcred->p_svgid != pcred->p_rgid)
        !          1021:                return (EFAULT);
        !          1022:        if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
        !          1023:            p->p_rlimit[RLIMIT_CORE].rlim_cur)
        !          1024:                return (EFAULT);
        !          1025:        sprintf(name, "core.%s", p->p_comm);
        !          1026:        nd.ni_dirp = name;
        !          1027:        nd.ni_segflg = UIO_SYSSPACE;
        !          1028:        if (error = vn_open(&nd, p, O_CREAT|FWRITE, 0644))
        !          1029:                return (error);
        !          1030:        vp = nd.ni_vp;
        !          1031:        if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred, p) ||
        !          1032:            vattr.va_nlink != 1) {
        !          1033:                error = EFAULT;
        !          1034:                goto out;
        !          1035:        }
        !          1036:        VATTR_NULL(&vattr);
        !          1037:        vattr.va_size = 0;
        !          1038:        VOP_SETATTR(vp, &vattr, cred, p);
        !          1039:        p->p_acflag |= ACORE;
        !          1040:        bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc));
        !          1041:        fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
        !          1042: #ifdef HPUXCOMPAT
        !          1043:        /*
        !          1044:         * BLETCH!  If we loaded from an HPUX format binary file
        !          1045:         * we have to dump an HPUX style user struct so that the
        !          1046:         * HPUX debuggers can grok it.
        !          1047:         */
        !          1048:        if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXBIN)
        !          1049:                error = hpuxdumpu(vp, cred);
        !          1050:        else
        !          1051: #endif
        !          1052:        error = vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES),
        !          1053:            (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *) NULL,
        !          1054:            p);
        !          1055:        if (error == 0)
        !          1056:                error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
        !          1057:                    (int)ctob(vm->vm_dsize), (off_t)ctob(UPAGES), UIO_USERSPACE,
        !          1058:                    IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
        !          1059:        if (error == 0)
        !          1060:                error = vn_rdwr(UIO_WRITE, vp,
        !          1061:                    (caddr_t) trunc_page(USRSTACK - ctob(vm->vm_ssize)),
        !          1062:                    round_page(ctob(vm->vm_ssize)),
        !          1063:                    (off_t)ctob(UPAGES) + ctob(vm->vm_dsize), UIO_USERSPACE,
        !          1064:                    IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
        !          1065: out:
        !          1066:        VOP_UNLOCK(vp);
        !          1067:        error1 = vn_close(vp, FWRITE, cred, p);
        !          1068:        if (error == 0)
        !          1069:                error = error1;
        !          1070:        return (error);
        !          1071: }
        !          1072: 
        !          1073: /*
        !          1074:  * Nonexistent system call-- signal process (may want to handle it).
        !          1075:  * Flag error in case process won't see signal immediately (blocked or ignored).
        !          1076:  */
        !          1077: /* ARGSUSED */
        !          1078: nosys(p, args, retval)
        !          1079:        struct proc *p;
        !          1080:        void *args;
        !          1081:        int *retval;
        !          1082: {
        !          1083: 
        !          1084:        psignal(p, SIGSYS);
        !          1085:        return (EINVAL);
        !          1086: }

unix.superglobalmegacorp.com

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