Annotation of researchv10dc/sys/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: #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.