Annotation of researchv9/sys.vax/sys/sig.c, revision 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.