Annotation of researchv10no/sys/os/sig.c, revision 1.1

1.1     ! root        1: #include "sys/param.h"
        !             2: #include "sys/systm.h"
        !             3: #include "sys/user.h"
        !             4: #include "sys/proc.h"
        !             5: #include "sys/inode.h"
        !             6: #include "sys/mtpr.h"
        !             7: #include "sys/conf.h"
        !             8: #include "sys/vlimit.h"
        !             9: #include "sys/text.h"
        !            10: 
        !            11: /*
        !            12:  * Send the specified signal to
        !            13:  * all processes with 'pgrp' as
        !            14:  * process group.
        !            15:  * Called by tty code for quits and
        !            16:  * interrupts.
        !            17:  */
        !            18: gsignal(pgrp, sig)
        !            19: register pgrp;
        !            20: {
        !            21:        register struct proc *p;
        !            22: 
        !            23:        if(pgrp == 0)
        !            24:                return;
        !            25:        for(p = proc; p < procNPROC; p++)
        !            26:                if (p->p_stat != 0 && p->p_pgrp == pgrp)
        !            27:                        psignal(p, sig);
        !            28: }
        !            29: 
        !            30: /*
        !            31:  * Send the specified signal to
        !            32:  * the specified process.
        !            33:  */
        !            34: psignal(p, sig)
        !            35: register struct proc *p;
        !            36: register int sig;
        !            37: {
        !            38:        register s;
        !            39:        register int (*action)();
        !            40:        long sigmask;
        !            41: 
        !            42:        if ((unsigned)sig >= NSIG
        !            43:        ||  p->p_stat == 0 || p->p_stat == SZOMB)
        !            44:                return;
        !            45:        sigmask = SIGMASK(sig);
        !            46: 
        !            47:        /*
        !            48:         * If proc is traced, always give parent a chance.
        !            49:         * Otherwise get the signal action from the bits in the proc table.
        !            50:         */
        !            51:        if (p->p_flag & STRC)
        !            52:                action = SIG_DFL;
        !            53:        else
        !            54:                action = P_SIGVAL(p, sigmask);
        !            55:        if (action == SIG_IGN)
        !            56:                return;
        !            57: #define        stops   (SIGMASK(SIGSTOP)|SIGMASK(SIGTSTP)|SIGMASK(SIGTTIN)|SIGMASK(SIGTTOU))
        !            58:        if (sig) {
        !            59:                p->p_sig |= sigmask;
        !            60:                switch (sig) {
        !            61: 
        !            62:                case SIGTERM:
        !            63:                        if ((p->p_flag&STRC) != 0 || action != SIG_DFL)
        !            64:                                break;
        !            65:                        /* fall into ... */
        !            66: 
        !            67:                case SIGKILL:
        !            68:                        if (p->p_nice > NZERO)
        !            69:                                p->p_nice = NZERO;
        !            70:                        break;
        !            71: 
        !            72:                case SIGCONT:
        !            73:                        p->p_sig &= ~stops;
        !            74:                        break;
        !            75: 
        !            76:                case SIGSTOP:
        !            77:                case SIGTSTP:
        !            78:                case SIGTTIN:
        !            79:                case SIGTTOU:
        !            80:                        p->p_sig &= ~SIGMASK(SIGCONT);
        !            81:                        break;
        !            82:                }
        !            83:        }
        !            84: #undef stops
        !            85:        /*
        !            86:         * Defer further processing for signals which are held.
        !            87:         */
        !            88:        if (action == SIG_HOLD)
        !            89:                return;
        !            90:        s = spl6();
        !            91:        switch (p->p_stat) {
        !            92: 
        !            93:        case SSLEEP:
        !            94:                /*
        !            95:                 * If process is sleeping at negative priority
        !            96:                 * we can't interrupt the sleep... the signal will
        !            97:                 * be noticed when the process returns through
        !            98:                 * trap() or syscall().
        !            99:                 */
        !           100:                if (p->p_pri <= PZERO)
        !           101:                        goto out;
        !           102:                /*
        !           103:                 * Process is sleeping and traced... make it runnable
        !           104:                 * so it can discover the signal in issig() and stop
        !           105:                 * for the parent.
        !           106:                 */
        !           107:                if (p->p_flag&STRC)
        !           108:                        goto run;
        !           109:                switch (sig) {
        !           110: 
        !           111:                case SIGSTOP:
        !           112:                case SIGTSTP:
        !           113:                case SIGTTIN:
        !           114:                case SIGTTOU:
        !           115:                        /*
        !           116:                         * These are the signals which by default
        !           117:                         * stop a process.
        !           118:                         */
        !           119:                        if (action != SIG_DFL)
        !           120:                                goto run;
        !           121:                        /*
        !           122:                         * Don't clog system with children of init
        !           123:                         * stopped from the keyboard.
        !           124:                         */
        !           125:                        if (sig != SIGSTOP && p->p_pptr == &proc[INITPID]) {
        !           126:                                psignal(p, SIGKILL);
        !           127:                                p->p_sig &= ~sigmask;
        !           128:                                splx(s);
        !           129:                                return;
        !           130:                        }
        !           131:                        p->p_sig &= ~sigmask;
        !           132:                        p->p_cursig = sig;
        !           133:                        stop(p);
        !           134:                        goto out;
        !           135: 
        !           136:                case SIGTINT:
        !           137:                case SIGCHLD:
        !           138:                        /*
        !           139:                         * These signals are special in that they
        !           140:                         * don't get propogated... if the process
        !           141:                         * isn't interested, forget it.
        !           142:                         */
        !           143:                        if (action != SIG_DFL)
        !           144:                                goto run;
        !           145:                        p->p_sig &= ~sigmask;           /* take it away */
        !           146:                        goto out;
        !           147: 
        !           148:                default:
        !           149:                        /*
        !           150:                         * All other signals cause the process to run
        !           151:                         */
        !           152:                        goto run;
        !           153:                }
        !           154:                /*NOTREACHED*/
        !           155: 
        !           156:        case SSTOP:
        !           157:                /*
        !           158:                 * If traced process is already stopped,
        !           159:                 * then no further action is necessary,
        !           160:                 * except to guarantee a sure SIGKILL and
        !           161:                 * prevent multiple SIGSTOP's.
        !           162:                 */
        !           163:                if ((p->p_flag&STRC) && sig != SIGKILL && sig != SIGSTOP)
        !           164:                        goto out;
        !           165:                switch (sig) {
        !           166: 
        !           167:                case SIGKILL:
        !           168:                        /*
        !           169:                         * Kill signal always sets processes running.
        !           170:                         */
        !           171:                        goto run;
        !           172: 
        !           173:                case SIGCONT:
        !           174:                        /*
        !           175:                         * If the process catches SIGCONT, let it handle
        !           176:                         * the signal itself.  If it isn't waiting on
        !           177:                         * an event, then it goes back to run state.
        !           178:                         * Otherwise, process goes back to sleep state.
        !           179:                         */
        !           180:                        if (action != SIG_DFL || p->p_wchan == 0)
        !           181:                                goto run;
        !           182:                        p->p_stat = SSLEEP;
        !           183:                        goto out;
        !           184: 
        !           185:                case SIGSTOP:
        !           186:                case SIGTSTP:
        !           187:                case SIGTTIN:
        !           188:                case SIGTTOU:
        !           189:                        /*
        !           190:                         * Already stopped, don't need to stop again.
        !           191:                         * (If we did the shell could get confused.)
        !           192:                         */
        !           193:                        p->p_sig &= ~sigmask;           /* take it away */
        !           194:                        goto out;
        !           195: 
        !           196:                default:
        !           197:                        /*
        !           198:                         * If process is sleeping interruptibly, then
        !           199:                         * unstick it so that when it is continued
        !           200:                         * it can look at the signal.
        !           201:                         * But don't setrun the process as its not to
        !           202:                         * be unstopped by the signal alone.
        !           203:                         */
        !           204:                        if (p->p_wchan && p->p_pri > PZERO)
        !           205:                                unsleep(p);
        !           206:                        goto out;
        !           207:                }
        !           208:                /*NOTREACHED*/
        !           209: 
        !           210:        default:
        !           211:                /*
        !           212:                 * SRUN, SIDL, SZOMB do nothing with the signal,
        !           213:                 * other than kicking ourselves if we are running.
        !           214:                 * It will either never be noticed, or noticed very soon.
        !           215:                 */
        !           216:                if (p == u.u_procp && !noproc)
        !           217:                        aston();
        !           218:                goto out;
        !           219:        }
        !           220:        /*NOTREACHED*/
        !           221: run:
        !           222:        /*
        !           223:         * Raise priority to at least PUSER.
        !           224:         */
        !           225:        if (p->p_pri > PUSER)
        !           226:                if ((p != u.u_procp || noproc) && p->p_stat == SRUN &&
        !           227:                    (p->p_flag & SLOAD)) {
        !           228:                        remrq(p);
        !           229:                        p->p_pri = PUSER;
        !           230:                        setrq(p);
        !           231:                } else
        !           232:                        p->p_pri = PUSER;
        !           233:        setrun(p);
        !           234: out:
        !           235:        splx(s);
        !           236: }
        !           237: 
        !           238: /*
        !           239:  * Returns true if the current
        !           240:  * process has a signal to process.
        !           241:  * The signal to process is put in p_cursig.
        !           242:  * This is asked at least once each time a process enters the
        !           243:  * system (though this can usually be done without actually
        !           244:  * calling issig by checking the pending signal masks.)
        !           245:  * A signal does not do anything
        !           246:  * directly to a process; it sets
        !           247:  * a flag that asks the process to
        !           248:  * do something to itself.
        !           249:  */
        !           250: issig()
        !           251: {
        !           252:        register struct proc *p = u.u_procp;
        !           253:        register int sig;
        !           254:        long sigbits, sigmask, trmask;
        !           255:        int (*action)();
        !           256: 
        !           257:        for (;;) {
        !           258:                sigbits = p->p_sig;
        !           259:                if ((p->p_flag&STRC) == 0)
        !           260:                        sigbits &= ~p->p_ignsig;
        !           261:                if (sigbits == 0)
        !           262:                        break;
        !           263:                sig = (sigbits & SIGMASK(SIGKILL)) ? SIGKILL : ffs(sigbits);
        !           264:                sigmask = SIGMASK(sig);
        !           265:                p->p_sig &= ~sigmask;           /* take the signal! */
        !           266:                p->p_cursig = sig;
        !           267:                trmask = SIGMASK(SIGSTOP);      /* SIGSTOP always traced */
        !           268:                if (p->p_flag&STRC) {
        !           269:                        register struct proc *pp = p;
        !           270:                        do if (pp->p_trace) {
        !           271:                                        trmask |= pp->p_trace->i_un.i_sigmask;
        !           272:                                        break;
        !           273:                        } while ((pp = pp->p_pptr) && pp->p_flag&STRC);
        !           274:                }
        !           275:                trmask &= sigmask & (~SIGMASK(SIGKILL));
        !           276:                if (trmask) {
        !           277:                        /*
        !           278:                         * If traced, always stop.
        !           279:                         */
        !           280:                        stop(p);
        !           281:                        swtch();
        !           282:                        /*
        !           283:                         * If debugger wants us to take the signal,
        !           284:                         * then it will leave it in p->p_cursig;
        !           285:                         * otherwise we just look for signals again.
        !           286:                         */
        !           287:                        if ((sig = p->p_cursig) == 0)
        !           288:                                continue;
        !           289:                }
        !           290:                if ((action = u.u_signal[sig]) == SIG_DFL) {
        !           291:                        /*
        !           292:                         * Don't take default actions on system processes.
        !           293:                         */
        !           294:                        if (p->p_flag & SSYS)
        !           295:                                break;
        !           296:                        switch (sig) {
        !           297:                        case SIGTSTP:
        !           298:                        case SIGTTIN:
        !           299:                        case SIGTTOU:
        !           300:                                /*
        !           301:                                 * Children of init aren't allowed to stop
        !           302:                                 * on signals from the keyboard.
        !           303:                                 */
        !           304:                                if (p->p_pptr == &proc[INITPID]) {
        !           305:                                        psignal(p, SIGKILL);
        !           306:                                        continue;
        !           307:                                }
        !           308:                                /* fall into ... */
        !           309: 
        !           310:                        case SIGSTOP:
        !           311:                                if (trmask)
        !           312:                                        continue;
        !           313:                                stop(p);
        !           314:                                swtch();
        !           315:                                continue;
        !           316: 
        !           317:                        case SIGTINT:
        !           318:                        case SIGCONT:
        !           319:                        case SIGCHLD:
        !           320:                                /*
        !           321:                                 * These signals are normally not
        !           322:                                 * sent if the action is the default.
        !           323:                                 * This can happen only if you reset the
        !           324:                                 * signal action from an action which was
        !           325:                                 * not deferred to SIG_DFL before the
        !           326:                                 * system gets a chance to post the signal.
        !           327:                                 */
        !           328:                                continue;               /* == ignore */
        !           329: 
        !           330:                        default:
        !           331:                                goto send;
        !           332:                        }
        !           333:                } else if (action == SIG_IGN || action == SIG_HOLD) {
        !           334:                        /*
        !           335:                         * shouldn't happen unless process traced;
        !           336:                         * see psignal
        !           337:                         */
        !           338:                        if ((p->p_flag&STRC) == 0)
        !           339:                                printf("issig %d\n", sig);
        !           340:                        continue;
        !           341:                } else {
        !           342:                        /*
        !           343:                         * This signal has an action, let
        !           344:                         * psig process it.
        !           345:                         */
        !           346:                        goto send;
        !           347:                }
        !           348:        }
        !           349:        /*
        !           350:         * Didn't find a signal to send.
        !           351:         */
        !           352:        p->p_cursig = 0;
        !           353:        return (0);
        !           354: 
        !           355: send:
        !           356:        /*
        !           357:         * Let psig process the signal.
        !           358:         */
        !           359:        return (sig);
        !           360: }
        !           361: 
        !           362: #ifndef vax
        !           363: ffs(mask)
        !           364: register long mask;
        !           365: {
        !           366:        register int i;
        !           367: 
        !           368:        for(i=1; i<NSIG; i++) {
        !           369:                if(mask & 1)
        !           370:                        return(i);
        !           371:                mask >>= 1;
        !           372:        }
        !           373:        return(0);
        !           374: }
        !           375: #endif
        !           376: 
        !           377: /*
        !           378:  * Put the argument process into the stopped
        !           379:  * state and notify the parent via wakeup and/or signal.
        !           380:  */
        !           381: stop(p)
        !           382:        register struct proc *p;
        !           383: {
        !           384: 
        !           385:        p->p_stat = SSTOP;
        !           386:        p->p_flag &= ~SWTED;
        !           387:        wakeup((caddr_t)p->p_pptr);
        !           388:        wakeup((caddr_t)p->p_trace);
        !           389:        /*
        !           390:         * Avoid sending signal to parent if process is traced
        !           391:         */
        !           392:        if (p->p_flag&STRC)
        !           393:                return;
        !           394:        psignal(p->p_pptr, SIGCHLD);
        !           395: }
        !           396: 
        !           397: /*
        !           398:  * Perform the action specified by
        !           399:  * the current signal.
        !           400:  * The usual sequence is:
        !           401:  *     if(issig())
        !           402:  *             psig();
        !           403:  * The signal bit has already been cleared by issig,
        !           404:  * and the current signal number stored in p->p_cursig.
        !           405:  */
        !           406: psig()
        !           407: {
        !           408:        register struct proc *rp = u.u_procp;
        !           409:        register int n = rp->p_cursig;
        !           410:        long sigmask = SIGMASK(n);
        !           411:        register int (*action)();
        !           412: 
        !           413:        if (rp->p_cursig == 0)
        !           414:                panic("psig");
        !           415:        action = u.u_signal[n];
        !           416:        if (action != SIG_DFL) {
        !           417:                if (action == SIG_IGN || action == SIG_HOLD)
        !           418:                        panic("psig action");
        !           419:                u.u_error = 0;
        !           420:                if(n != SIGILL && n != SIGTRAP)
        !           421:                        u.u_signal[n] = 0;
        !           422:                /*
        !           423:                 * If this catch value indicates automatic holding of
        !           424:                 * subsequent signals, set the hold value.
        !           425:                 */
        !           426:                if (SIGISDEFER(action)) {
        !           427:                        (void) spl6();
        !           428:                        P_SETHOLD(rp, sigmask);
        !           429:                        u.u_signal[n] = SIG_HOLD;
        !           430:                        (void) spl0();
        !           431:                        action = SIGUNDEFER(action);
        !           432:                }
        !           433:                sendsig(action, n);
        !           434:                rp->p_cursig = 0;
        !           435:                return;
        !           436:        }
        !           437:        switch (n) {
        !           438: 
        !           439:        case SIGILL:
        !           440:        case SIGIOT:
        !           441:        case SIGBUS:
        !           442:        case SIGQUIT:
        !           443:        case SIGTRAP:
        !           444:        case SIGEMT:
        !           445:        case SIGFPE:
        !           446:        case SIGSEGV:
        !           447:        case SIGSYS:
        !           448:                u.u_arg[0] = n;
        !           449:                if(core())
        !           450:                        n += 0200;
        !           451:        }
        !           452:        exit(n);
        !           453: }
        !           454: 
        !           455: /*
        !           456:  * Create a core image on the file "core"
        !           457:  * If you are looking for protection glitches,
        !           458:  * there are probably a wealth of them here
        !           459:  * when this occurs to a suid command.
        !           460:  *
        !           461:  * It writes UPAGES block of the
        !           462:  * user.h area followed by the entire
        !           463:  * data+stack segments.
        !           464:  */
        !           465: core()
        !           466: {
        !           467:        register struct inode *ip;
        !           468:        struct argnamei nmarg;
        !           469:        struct proc coreproc;
        !           470: 
        !           471:        if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= u.u_limit[LIM_CORE])
        !           472:                return (0);
        !           473:        coreproc = *u.u_procp;
        !           474:        u.u_stack[0] = (int)&coreproc;
        !           475:        u.u_error = 0;
        !           476:        nmarg = nilargnamei;
        !           477:        nmarg.flag = NI_CREAT;
        !           478:        nmarg.un.mode = 0666 & ~u.u_cmask;
        !           479:        ip = namei("core", SEGSYS, &nmarg, 0);
        !           480:        if(ip == NULL)
        !           481:                return(0);
        !           482:        if(!access(ip, IWRITE) &&
        !           483:           (ip->i_mode&IFMT) == IFREG && ip->i_nlink==1) {
        !           484:                (*fstypsw[ip->i_fstyp]->t_trunc)(ip);
        !           485:                if (u.u_procp->p_textp) /* permission not greater than text */
        !           486:                        ip->i_mode &= u.u_procp->p_textp->x_iptr->i_mode;
        !           487:                ip->i_uid = u.u_uid;    /* in case it existed already */
        !           488:                ip->i_gid = u.u_gid;
        !           489:                u.u_offset = ltoL(0);
        !           490:                u.u_base = (caddr_t)&u;
        !           491:                u.u_count = ctob(UPAGES);
        !           492:                u.u_segflg = SEGSYS;
        !           493:                writei(ip);
        !           494:                u.u_base = (char *)ctob(u.u_tsize);
        !           495:                u.u_count = ctob(u.u_dsize);
        !           496:                u.u_segflg = SEGUDATA;
        !           497:                writei(ip);
        !           498:                u.u_base = (char *)(USRSTACK - ctob(u.u_ssize));
        !           499:                u.u_count = ctob(u.u_ssize);
        !           500:                writei(ip);
        !           501:        } else
        !           502:                u.u_error = EFAULT;
        !           503:        iput(ip);
        !           504:        return(u.u_error==0);
        !           505: }
        !           506: 
        !           507: /*
        !           508:  * grow the stack to include the SP
        !           509:  * true return if successful.
        !           510:  */
        !           511: grow(sp)
        !           512: unsigned sp;
        !           513: {
        !           514:        register si;
        !           515: 
        !           516:        if(sp >= USRSTACK-ctob(u.u_ssize))
        !           517:                return(0);
        !           518:        si = clrnd(btoc((USRSTACK-sp)) - u.u_ssize + SINCR);
        !           519:        if (ctob(u.u_ssize+si) > u.u_limit[LIM_STACK])
        !           520:                return(0);
        !           521:        if (chksize(u.u_tsize, u.u_dsize, u.u_ssize+si))
        !           522:                return(0);
        !           523:        if (swpexpand(u.u_dsize, u.u_ssize+si, &u.u_dmap, &u.u_smap)==0)
        !           524:                return(0);
        !           525:        
        !           526:        expand(si, P1BR);
        !           527:        return(1);
        !           528: }

unix.superglobalmegacorp.com

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