Annotation of researchv9/sys.vax/sys/sig.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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