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

unix.superglobalmegacorp.com

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