Annotation of coherent/d/PS2_KERNEL/coh.386/sig.c, revision 1.1.1.1

1.1       root        1: /* $Header: /kernel/kersrc/coh.386/RCS/sig.c,v 1.2 92/08/04 12:34:36 bin Exp Locker: bin $ */
                      2: /* (lgl-
                      3:  *     The information contained herein is a trade secret of Mark Williams
                      4:  *     Company, and  is confidential information.  It is provided  under a
                      5:  *     license agreement,  and may be  copied or disclosed  only under the
                      6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      7:  *     material without the express written authorization of Mark Williams
                      8:  *     Company or persuant to the license agreement is unlawful.
                      9:  *
                     10:  *     COHERENT Version 2.3.37
                     11:  *     Copyright (c) 1982, 1983, 1984.
                     12:  *     An unpublished work by Mark Williams Company, Chicago.
                     13:  *     All rights reserved.
                     14:  -lgl) */
                     15: /*
                     16:  * Coherent.
                     17:  * Signal handling.
                     18:  *
                     19:  * $Log:       sig.c,v $
                     20:  * Revision 1.2  92/08/04  12:34:36  bin
                     21:  * changed for ker 59
                     22:  * 
                     23:  * Revision 1.2  92/01/06  12:00:24  hal
                     24:  * Compile with cc.mwc.
                     25:  * 
                     26:  * Revision 1.1        88/03/24  16:14:24      src
                     27:  * Initial revision
                     28:  * 
                     29:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/sig.c
                     30:  * New seg struct now used to allow extended addressing.
                     31:  *
                     32:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/sig.c
                     33:  * sigdump() initializes the (new) (IO).io_flag field to 0.
                     34:  */
                     35: #include <sys/coherent.h>
                     36: #include <errno.h>
                     37: #include <sys/ino.h>
                     38: #include <sys/inode.h>
                     39: #include <sys/io.h>
                     40: #include <sys/proc.h>
                     41: #include <sys/ptrace.h>
                     42: #include <sys/sched.h>
                     43: #include <sys/seg.h>
                     44: #include <signal.h>
                     45: 
                     46: /*
                     47:  * Set up the action to be taken on a signal.
                     48:  */
                     49: usigsys(signal, func)
                     50: int    signal;
                     51: register void (*func)();
                     52: {
                     53:        register PROC *pp;
                     54:        register sig_t s;
                     55:        register int (*old_sig)();
                     56:        int     sigtype;
                     57: 
                     58:        sigtype = signal & ~0xFF;
                     59:        signal ^= sigtype;
                     60: 
                     61:        pp = SELF;
                     62:        if (signal<=0 || signal>NSIG || signal==SIGKILL) {
                     63:                u.u_error = EINVAL;
                     64:                return;
                     65:        }
                     66: 
                     67:        /*
                     68:         * In order to avoid runaway, don't allow user to set
                     69:         * handler for SIGSEGV to anything but SIG_DFL.
                     70:         *
                     71:         * We should do something more sophisticated, like detecting
                     72:         * two SEGV's in a row and then killing the process.
                     73:         */
                     74:        if (signal == SIGSEGV && func != SIG_DFL) {
                     75:                u.u_error = EINVAL;
                     76:                return;
                     77:        }
                     78: 
                     79:        if (sigtype==SIGDEFER || sigtype==0) {
                     80:                if (func==SIG_IGN)
                     81:                        sigtype = SIGIGNORE;
                     82:                if (func==SIG_HOLD)
                     83:                        sigtype = SIGHOLD;
                     84:        }
                     85: 
                     86:        s = (sig_t)1 << --signal;
                     87:        if (pp->p_isig&s)
                     88:                old_sig = SIG_IGN;
                     89:        else if (pp->p_hsig&s)
                     90:                old_sig = SIG_HOLD;
                     91:        else
                     92:                old_sig = u.u_sfunc[signal];
                     93: 
                     94:        switch (sigtype) {
                     95:        case SIGHOLD:
                     96:                pp->p_hsig |= s;
                     97:                break;
                     98:        case SIGRELSE:
                     99:                pp->p_hsig &= ~s;
                    100:                if (nondsig()) {
                    101:                        T_PIGGY( 0x100, printf("a(s)"); );
                    102:                        actvsig();
                    103:                }
                    104:        case SIGIGNORE:
                    105:                pp->p_dfsig &= ~s;      /* No longer defaulted.  */
                    106:                pp->p_isig |= s;        /* Mark signal as ignored.  */
                    107:                pp->p_ssig &= ~s;       /* Turn off any pending signal.  */
                    108:                break;
                    109:        case 0:                         /* old system entry */
                    110:        case SIGDEFER:                  /* new system entry */
                    111:                u.u_sigreturn = (void (*)())u.u_regl[EDX];
                    112:                u.u_sfunc[signal] = func;
                    113:                /*
                    114:                 * Be sure to mark the signal as defaulted or not.
                    115:                 */
                    116:                if (SIG_DFL == func) {
                    117:                        pp->p_dfsig |= s;
                    118:                } else {
                    119:                        pp->p_dfsig &= ~s;
                    120:                }
                    121:                /*
                    122:                 * The signal is no longer ignored or held, and
                    123:                 * any pending signal is lost.
                    124:                 */
                    125:                pp->p_isig &= ~s;
                    126:                pp->p_hsig &= ~s;
                    127:                pp->p_ssig &= ~s;
                    128:                if (sigtype==SIGDEFER)
                    129:                        pp->p_dsig |= s;
                    130:                else
                    131:                        pp->p_dsig &= ~s;
                    132:                break;
                    133:        /* SIGPAUSE not done yet */
                    134:        default:
                    135:                u.u_error = SIGSYS;
                    136:                break;
                    137:        }
                    138:        return old_sig;
                    139: }
                    140: 
                    141: 
                    142: /*
                    143:  * Send a signal to the process `pp'.
                    144:  */
                    145: sendsig(sig, pp)
                    146: register unsigned sig;
                    147: register PROC *pp;
                    148: {
                    149:        register sig_t f;
                    150:        register int s;
                    151: 
                    152: 
                    153:        T_PIGGY( 0x40000000,
                    154:            printf("<send sig: %d, id: %d, state: %x, flags: %x, event: %x>",
                    155:                   sig, pp->p_pid, pp->p_state, pp->p_flags, pp->p_event);
                    156:        ); /* T_PIGGY() */
                    157: 
                    158:        /*
                    159:         * Convert the signal to a bit position.
                    160:         */
                    161:        f = ((sig_t)1) << (sig-1);
                    162: 
                    163:        /*
                    164:         * If the signal is ignored, do nothing.
                    165:         */
                    166:        if (pp->p_isig&f) {
                    167:                return;
                    168:        }
                    169: 
                    170:        /*
                    171:         * This bit causes SIGCHLD to be ignored here in sendsig().
                    172:         */
                    173:        T_PIGGY( 0x10000000, {
                    174:                if (SIGCHLD == sig) {
                    175:                        printf("SIGCHLD ignored, ");
                    176:                        return;
                    177:                }
                    178:        }
                    179:        );
                    180: 
                    181:        /*
                    182:         * I do not understand delayed or held signals.
                    183:         */
                    184:        if ((pp->p_ssig & f) && (pp->p_hsig|pp->p_dsig) & f)
                    185:                return;
                    186:        
                    187:        /*
                    188:         * Acutally send the signal by flagging the needed bit.
                    189:         */
                    190:        pp->p_ssig |= f;
                    191: 
                    192:        /*
                    193:         * If the process is sleeping, wake it up so that
                    194:         * it can process this signal.
                    195:         */
                    196:        if (pp->p_state == PSSLEEP) {
                    197:                s = sphi();
                    198:                pp->p_lback->p_lforw = pp->p_lforw;
                    199:                pp->p_lforw->p_lback = pp->p_lback;
                    200:                addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK);
                    201:                setrun(pp);
                    202:                spl(s);
                    203:        }
                    204: }
                    205: 
                    206: /*
                    207:  * Return signal number if we have a non ignored or delayed signal, else zero.
                    208:  */
                    209: nondsig()
                    210: {
                    211:        register PROC *pp;
                    212:        register sig_t mask;
                    213:        register int signo;
                    214: 
                    215:        pp = SELF;
                    216:        signo = 0;
                    217:        /*
                    218:         * Turn off all ignored signals.
                    219:         */
                    220:        pp->p_ssig &= ~pp->p_isig;
                    221:        /*
                    222:         * If any signals have arrived, but which are not held,
                    223:         * figure out what they are.
                    224:         */
                    225:        if (pp->p_ssig&~pp->p_hsig) {
                    226:                /*
                    227:                 * There is at least one signal.  Extract its number
                    228:                 * from the signal bits.
                    229:                 */
                    230:                mask = (sig_t) 1;
                    231:                signo += 1;
                    232:                while (((pp->p_ssig&~pp->p_hsig) & mask) == 0) {
                    233:                        mask <<= 1;
                    234:                        signo += 1;
                    235:                }
                    236:        }
                    237:        return (signo);
                    238: }
                    239: 
                    240: /*
                    241:  * If we have a signal that isn't ignored, activate it.
                    242:  */
                    243: actvsig()
                    244: {
                    245:        register int n;
                    246:        register PROC *pp;
                    247:        register int (*func)();
                    248:        sig_t s;
                    249: 
                    250: 
                    251:        /*
                    252:         * Fetch an unprocessed signal.
                    253:         * Return if there are none.
                    254:         */
                    255:        if ((n = nondsig()) == 0)
                    256:                return;
                    257: 
                    258:        T_PIGGY( 0x40000, {
                    259:                if (SIGCHLD == n) {
                    260:                        printf("-");
                    261:                        return;
                    262:                }
                    263:        } );
                    264: 
                    265:        pp = SELF;
                    266: 
                    267:        /*
                    268:         * Reset the signal to indicate that it has been processed.
                    269:         */
                    270:        --n;
                    271:        pp->p_ssig &= ~((sig_t)1<<n);
                    272: 
                    273:        /*
                    274:         * Fetch the user function that goes with this signal.
                    275:         */
                    276:        func = u.u_sfunc[n];
                    277: 
                    278:        /*
                    279:         * Store the signal number in the u area.  This is how
                    280:         * a core dump records the death signal.
                    281:         */
                    282:        u.u_signo = ++n;
                    283: 
                    284:        /*
                    285:         * If the signal is not defaulted, go run the requested
                    286:         * function.
                    287:         */
                    288:        if (func != SIG_DFL) {
                    289:                if (XMODE_286)
                    290:                        oldsigstart(n, func);
                    291:                else
                    292:                        msigstart(n, func);
                    293:                return;
                    294:        }
                    295: 
                    296:        /*
                    297:         * ASSERTION:  the signal being processed is SIG_DFL'd.
                    298:         */
                    299: 
                    300:        /*
                    301:         * msysgen() is a nop for COHERENT 4.0.  The comment in the
                    302:         * assembly code is "Nothing useful to save".
                    303:         */
                    304:        msysgen(u.u_sysgen);
                    305: 
                    306:        /*
                    307:         * Do something special for traced processes.  (?)
                    308:         */
                    309:        if (pp->p_flags&PFTRAC) {
                    310:                pp->p_flags |= PFWAIT;
                    311:                n = ptret();
                    312:                pp->p_flags &= ~(PFWAIT|PFSTOP);
                    313:                if (n == 0)
                    314:                        return;
                    315:        }
                    316: 
                    317:        /*
                    318:         * Some signals cause a core file to be written.
                    319:         */
                    320:        switch(n) {
                    321:        case SIGQUIT:
                    322:        case SIGILL:
                    323:        case SIGTRAP:
                    324:        case SIGABRT:
                    325:        case SIGFPE:
                    326:        case SIGSEGV:
                    327:        case SIGSYS:
                    328:                if (sigdump())
                    329:                        n |= 0200;
                    330:                break;
                    331:        }
                    332:        pexit(n);
                    333: }
                    334: 
                    335: /*
                    336:  * Create a dump of ourselves onto the file `core'.
                    337:  */
                    338: sigdump()
                    339: {
                    340:        register INODE *ip;
                    341:        register SR *srp;
                    342:        register SEG * sp;
                    343:        register int n;
                    344:        register paddr_t ssize;
                    345:        extern  int     DUMP_LIM;
                    346: 
                    347:        if (SELF->p_flags&PFNDMP)
                    348:                return (0);
                    349:        u.u_io.io_seg  = IOSYS;
                    350:        u.u_io.io_flag = 0;
                    351:        /* Make the core with the real owners */
                    352:        schizo();
                    353:        if (ftoi("core", 'c')) {
                    354:                schizo();
                    355:                return (0);
                    356:        }
                    357:        if ((ip=u.u_cdiri) == NULL) {
                    358:                if ((ip=imake(IFREG|0644, 0)) == NULL) {
                    359:                        schizo();
                    360:                        return (0);
                    361:                }
                    362:        } else {
                    363:                if ((ip->i_mode&IFMT)!=IFREG
                    364:                 || iaccess(ip, IPW)==0
                    365:                 || getment(ip->i_dev, 1)==NULL) {
                    366:                        idetach(ip);
                    367:                        schizo();
                    368:                        return (0);
                    369:                }
                    370:                iclear(ip);
                    371:        }
                    372:        schizo();
                    373:        u.u_error = 0;
                    374:        u.u_io.io_seek = 0;
                    375:        for (srp=u.u_segl; u.u_error==0 && srp<&u.u_segl[NUSEG]; srp++) {
                    376:                if ((sp = srp->sr_segp)==NULL || (srp->sr_flag&SRFDUMP)==0)
                    377:                        continue;
                    378:                u.u_io.io_seg = IOPHY;
                    379:                u.u_io.io.pbase = MAPIO(sp->s_vmem, 0);
                    380:                u.u_io.io_flag = 0;
                    381:                ssize = sp->s_size;
                    382:                if (ssize > DUMP_LIM) {
                    383:                        printf("seg %d truncated from %d to %d bytes\n",
                    384:                          srp-u.u_segl, ssize, DUMP_LIM);
                    385:                        ssize = DUMP_LIM;
                    386:                }
                    387:                sp->s_lrefc++;
                    388:                while (u.u_error == 0 && ssize != 0) {
                    389:                        n = ssize > SCHUNK ? SCHUNK : ssize;
                    390:                        u.u_io.io_ioc = n;
                    391:                        iwrite(ip, &u.u_io);
                    392:                        u.u_io.io.pbase += n;
                    393:                        ssize -= (paddr_t)n;
                    394:                }
                    395:                sp->s_lrefc--;
                    396:        }
                    397:        idetach(ip);
                    398:        return (u.u_error==0);
                    399: }
                    400: 
                    401: /*
                    402:  * Send a ptrace command to the child.
                    403:  */
                    404: ptset(req, pid, addr, data)
                    405: unsigned req;
                    406: int *addr;
                    407: {
                    408: 
                    409:        register PROC *pp;
                    410: 
                    411:        lock(pnxgate);
                    412:        for (pp=procq.p_nforw; pp!=&procq; pp=pp->p_nforw)
                    413:                if (pp->p_pid == pid)
                    414:                        break;
                    415:        unlock(pnxgate);
                    416:        if (pp==&procq || (pp->p_flags&PFSTOP)==0 || pp->p_ppid!=SELF->p_pid){
                    417:                u.u_error = ESRCH;
                    418:                return;
                    419:        }
                    420:        lock(pts.pt_gate);
                    421:        pts.pt_req = req;
                    422:        pts.pt_pid = pid;
                    423:        pts.pt_addr = addr;
                    424:        pts.pt_data = data;
                    425:        pts.pt_errs = 0;
                    426:        pts.pt_rval = 0;
                    427:        pts.pt_busy = 1;
                    428:        wakeup((char *)&pts.pt_req);
                    429:        while (pts.pt_busy) {
                    430:                v_sleep((char *)&pts.pt_busy, CVPTSET, IVPTSET, SVPTSET, "ptrace");
                    431:                /* Send a ptrace command to the child.  */
                    432:        }
                    433:        u.u_error = pts.pt_errs;
                    434:        unlock(pts.pt_gate);
                    435:        return (pts.pt_rval);
                    436: }
                    437: 
                    438: /*
                    439:  * This routine is called when a child that is being traced receives a signal
                    440:  * that is not caught or ignored.  It follows up on any requests by the parent
                    441:  * and returns when done.
                    442:  */
                    443: ptret()
                    444: {
                    445:        register PROC *pp;
                    446:        register PROC *pp1;
                    447:        register int sign;
                    448:        unsigned off;
                    449: 
                    450:        pp = SELF;
                    451: next:
                    452:        u.u_error = 0;
                    453:        if (pp->p_ppid == 1)
                    454:                return (SIGKILL);
                    455:        sign = -1;
                    456:        lock(pnxgate);
                    457:        pp1 = &procq;
                    458:        for (;;) {
                    459:                if ((pp1=pp1->p_nforw) == &procq) {
                    460:                        sign = SIGKILL;
                    461:                        break;
                    462:                }
                    463:                if (pp1->p_pid != pp->p_ppid)
                    464:                        continue;
                    465:                if (pp1->p_state == PSSLEEP)
                    466:                        wakeup((char *)pp1);
                    467:                break;
                    468:        }
                    469:        unlock(pnxgate);
                    470:        while (sign < 0) {
                    471:                if (pts.pt_busy==0 || pp->p_pid!=pts.pt_pid) {
                    472:                        v_sleep((char *)&pts.pt_req, CVPTRET, IVPTRET, SVPTRET, "ptret");
                    473:                        /* Something about signals to a traced child.  */
                    474:                        goto next;
                    475:                }
                    476:                switch (pts.pt_req) {
                    477:                case 1:
                    478:                        if (XMODE_286) {
                    479:                                pts.pt_rval = getuwd(NBPS+pts.pt_addr);
                    480:                                break;
                    481:                        }
                    482:                case 2:
                    483:                        pts.pt_rval = getuwd(pts.pt_addr);
                    484:                        break;
                    485:                case 3:
                    486:                        off = (unsigned)pts.pt_addr;
                    487:                        if (off < UPASIZE)
                    488:                                pts.pt_rval = *(int *)((char *)&u+off);
                    489:                        else
                    490:                                u.u_error = EINVAL;
                    491:                        break;
                    492:                case 4:
                    493:                        if (XMODE_286) {
                    494:                                putuwd(NBPS+pts.pt_addr, pts.pt_data);
                    495:                                break;
                    496:                        }
                    497:                case 5:
                    498:                        putuwd(pts.pt_addr, pts.pt_data);
                    499:                        break;
                    500:                case 6:
                    501:                        if (msetuof(pts.pt_addr, pts.pt_data) == 0)
                    502:                                u.u_error = EINVAL;
                    503:                        break;
                    504:                case 7:
                    505:                        goto sig;
                    506:                case 8:
                    507:                        sign = SIGKILL;
                    508:                        break;
                    509:                case 9:
                    510:                        msigsin();
                    511:                sig:
                    512:                        if (pts.pt_data<0 || pts.pt_data>NSIG) {
                    513:                                u.u_error = EINVAL;
                    514:                                break;
                    515:                        }
                    516:                        sign = pts.pt_data;
                    517:                        if (pts.pt_addr != SIG_IGN)
                    518:                                msetppc((vaddr_t)pts.pt_addr);
                    519:                        break;
                    520:                default:
                    521:                        u.u_error = EINVAL;
                    522:                }
                    523:                if ((pts.pt_errs=u.u_error) == EFAULT)
                    524:                        pts.pt_errs = EINVAL;
                    525:                pts.pt_busy = 0;
                    526:                wakeup((char *)&pts.pt_busy);
                    527:        }
                    528:        return (sign);
                    529: }

unix.superglobalmegacorp.com

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