Annotation of cci/usr/src/bin/cdb/pt.c, revision 1.1

1.1     ! root        1: static char sccsid[] = "@(#)pt.c       2.10";
        !             2: 
        !             3: #include <errno.h>
        !             4: #include <signal.h>
        !             5: 
        !             6: #ifndef REGULUS
        !             7: #include <sys/param.h>
        !             8: #endif
        !             9: #ifdef SUN
        !            10: #define SYSTYPES 1     /* see basic.h */
        !            11: #endif
        !            12: #ifdef SYSIII
        !            13: #define SYSTYPES 1     /* see basic.h */
        !            14: #endif
        !            15: #include "cdb.h"
        !            16: #include "macdefs.h"
        !            17: 
        !            18: #ifdef SYSIII
        !            19: #include <termio.h>
        !            20: #ifdef REGULUS
        !            21: /* remove the two TCxxxxx and 
        !            22:  * add #include <sys/ioctl.h> when preporocessor is fixed 
        !            23:  */
        !            24: #define TCGETA 1
        !            25: #define TCSETAW 3
        !            26: #define EINTR -1
        !            27: #endif
        !            28: struct termio  histty, mytty;
        !            29: #endif
        !            30: 
        !            31: #ifdef BSD41
        !            32: #include <sgtty.h>
        !            33: struct sgttyb  histty, mytty;
        !            34: #endif
        !            35: 
        !            36: export int     vibp;   /* last breakpoint hit, if any */
        !            37: 
        !            38: export uint    vsig;
        !            39: uint   vstat, vstatHi, vstatLo;
        !            40: SAR    vmpSigSa[NSIG]; /* signal action array */
        !            41: 
        !            42: void Fixer();
        !            43: 
        !            44: #define cArgsMax       30
        !            45: char   *argvChild[cArgsMax];
        !            46: #define cbArgsMax      200
        !            47: export char    vsbArgsChild[cbArgsMax];  /* where we store args for child */
        !            48: 
        !            49: 
        !            50: /* N E X T   A R G */
        !            51: 
        !            52: export char * NextArg(psbIn)
        !            53: char   **psbIn;
        !            54: {
        !            55:        char    *sbRet;
        !            56: 
        !            57:        /* skip white space */
        !            58:        while (**psbIn == ' ' OR **psbIn == '\t')
        !            59:                (*psbIn)++;
        !            60:        if (**psbIn == chNull)
        !            61:                return(sbNil);  /* that's all, folks! */
        !            62:        sbRet = *psbIn; /* set current arg pointer */
        !            63:        while (**psbIn != chNull
        !            64:            AND **psbIn != ' '
        !            65:            AND **psbIn != '\t')
        !            66:                (*psbIn)++;     /* skip all non-white space characters */
        !            67:        **psbIn = chNull;       /* overwrite the tab, space, or 0 with a 0 */
        !            68:        (*psbIn)++;
        !            69:        return(sbRet);
        !            70: } /* NextArg */
        !            71: 
        !            72: 
        !            73: /* D O  A R G S */
        !            74: 
        !            75: export void DoArgs(sbProgram, sbArgs, argv, fReassign)
        !            76: char   *sbProgram, *sbArgs;
        !            77: char   **argv;
        !            78: FLAGT  fReassign;
        !            79: {
        !            80:        int             i;
        !            81:        char    *sbFile, *sbArgCur;
        !            82: 
        !            83:        for (i=0; i< cArgsMax; i++)
        !            84:                argv[i] = sbNil;
        !            85: 
        !            86:        *argv++ = sbProgram; /* set the filename */
        !            87: 
        !            88:        /* eat the arguments */
        !            89:        while ((sbArgs != sbNil)
        !            90:            AND (*sbArgs != chNull)) {
        !            91:                sbArgCur = NextArg(&sbArgs);
        !            92:                if (sbArgCur == sbNil)
        !            93:                        break;
        !            94:                /* check for indirection */
        !            95:                if (!fReassign
        !            96:                    OR ((*sbArgCur != '<') AND (*sbArgCur != '>')) ) {
        !            97:                        *argv++ = sbArgCur;     /* we just pass it on */
        !            98:                } 
        !            99:                else {
        !           100:                        /* find that file name */
        !           101:                        sbFile = sbArgCur + 1;  /* initially we assume `<foo' vs `< foo' */
        !           102:                        if (*sbFile == chNull) {
        !           103:                                /* there was white space between < and sbFile */
        !           104:                                sbFile = NextArg(&sbArgs);
        !           105:                                if (sbFile == sbNil) {
        !           106:                                        printf("Illegal indirection\n");
        !           107:                                        exit(1);
        !           108:                                } /* if */
        !           109:                        } /* if */
        !           110:                        if (*sbArgCur == '<') {
        !           111:                                /* changing stdin */
        !           112:                                close(0);
        !           113:                                if (open(sbFile, O_RDONLY) < 0) {
        !           114:                                        perror(sbFile);
        !           115:                                        exit(1);
        !           116:                                } /* if */
        !           117:                        } 
        !           118:                        else if (*sbArgCur == '>') {
        !           119:                                /* changing stdout */
        !           120:                                close(1);
        !           121:                                if (creat(sbFile, 0666) < 0) {
        !           122:                                        perror(sbFile);
        !           123:                                        exit(1);
        !           124:                                } /* if */
        !           125:                        } /* if */
        !           126:                } /* if */
        !           127:        } /* while */
        !           128:        *argv = sbNil;
        !           129: } /* DoArgs */
        !           130: 
        !           131: 
        !           132: /* P R I N T   S I G */
        !           133: 
        !           134: export void PrintSig(sig)
        !           135: int    sig;
        !           136: {
        !           137:        switch (sig) {
        !           138:        case SIGHUP:    
        !           139:                printf("Hangup"); 
        !           140:                break;
        !           141:        case SIGINT:    
        !           142:                printf("interrupt"); 
        !           143:                break;
        !           144:        case SIGQUIT:   
        !           145:                printf("quit"); 
        !           146:                break;
        !           147:        case SIGILL:    
        !           148:                printf("illegal instruction"); 
        !           149:                break;
        !           150:        case SIGTRAP:   
        !           151:                printf("breakpoint"); 
        !           152:                break;
        !           153:        case SIGIOT:    
        !           154:                printf("IOT instruction"); 
        !           155:                break;
        !           156:        case SIGEMT:    
        !           157:                printf("EMT instruction"); 
        !           158:                break;
        !           159:        case SIGFPE:    
        !           160:                printf("floating point exception"); 
        !           161:                break;
        !           162:        case SIGKILL:   
        !           163:                printf("kill"); 
        !           164:                break;
        !           165:        case SIGBUS:    
        !           166:                printf("bus error"); 
        !           167:                break;
        !           168:        case SIGSEGV:   
        !           169:                printf("segmentaion violation"); 
        !           170:                break;
        !           171:        case SIGSYS:    
        !           172:                printf("bad arg to sys call"); 
        !           173:                break;
        !           174:        case SIGPIPE:   
        !           175:                printf("write on pipe with no reader"); 
        !           176:                break;
        !           177:        case SIGALRM:   
        !           178:                printf("alarm clock"); 
        !           179:                break;
        !           180:        case SIGTERM:   
        !           181:                printf("software termination"); 
        !           182:                break;
        !           183: #ifdef SYSIII
        !           184:        case SIGUSR1:   
        !           185:                printf("user signal 1"); 
        !           186:                break;
        !           187:        case SIGUSR2:   
        !           188:                printf("user signal 2"); 
        !           189:                break;
        !           190:        case SIGCLD:    
        !           191:                printf("death of child"); 
        !           192:                break;
        !           193:        case SIGPWR:    
        !           194:                printf("power fail"); 
        !           195:                break;
        !           196: #endif
        !           197: #ifdef BSD41
        !           198: #ifdef BSD42
        !           199:        case SIGURG:    
        !           200:                printf("urgent condition on IO channel"); 
        !           201:                break;
        !           202:        case SIGIO:     
        !           203:                printf("input/output possible signal"); 
        !           204:                break;
        !           205:        case SIGVTALRM: 
        !           206:                printf("virtual time alarm"); 
        !           207:                break;
        !           208:        case SIGPROF:   
        !           209:                printf("profiling time alarm"); 
        !           210:                break;
        !           211: #endif
        !           212:        case SIGSTOP:   
        !           213:                printf("sendable stop signal not from tty"); 
        !           214:                break;
        !           215:        case SIGTSTP:   
        !           216:                printf("stop signal from tty"); 
        !           217:                break;
        !           218:        case SIGCONT:   
        !           219:                printf("attempt to continue a stopped process"); 
        !           220:                break;
        !           221:        case SIGCHLD:   
        !           222:                printf("child stop or exit"); 
        !           223:                break;
        !           224:        case SIGTTIN:   
        !           225:                printf("to readers pgrp upon background tty read");
        !           226:                break;
        !           227:        case SIGTTOU:   
        !           228:                printf("to writers pgrp upon background tty write");
        !           229:                break;
        !           230:        case SIGXCPU:   
        !           231:                printf("exceeded CPU time limit"); 
        !           232:                break;
        !           233:        case SIGXFSZ:   
        !           234:                printf("exceeded file size limit"); 
        !           235:                break;
        !           236: #endif
        !           237:        default:        
        !           238:                printf("signal %d", sig); 
        !           239:                break;
        !           240:        } /* switch */
        !           241: } /* PrintSig */
        !           242: 
        !           243: 
        !           244: /* I B P   F   W A I T */
        !           245: 
        !           246: export int IbpFWait(fDoBrk)
        !           247: FLAGT  fDoBrk;
        !           248: {
        !           249:        int             ibp, waitReturn;
        !           250:        pSAR    sa;
        !           251: 
        !           252: keepGoing:     /* we come here if the signal is not interesting */
        !           253: 
        !           254:        signal(SIGINT, SIG_IGN);        /* ignore INT - let child deal with it */
        !           255: 
        !           256:        while ( ((waitReturn=wait(&vstat)) != vpid) AND (waitReturn != -1) )
        !           257:                ;
        !           258: 
        !           259: #ifdef SYSIII
        !           260:        ioctl(0, TCGETA, &histty);      /* save his state, restore my state */
        !           261:        ioctl(0, TCSETAW, &mytty);
        !           262: #endif
        !           263: #ifdef BSD41
        !           264:        gtty(0, &histty);  /* save his state, restore my state */
        !           265:        stty(0, &mytty);
        !           266: #endif
        !           267:        signal(SIGINT, Fixer);  /* reconnect to the Fixer routine */
        !           268: 
        !           269:        GetState();
        !           270: 
        !           271:        vsig = vstatHi = vstat >> 8;
        !           272:        vstatLo = vstat & 0377;
        !           273:        vibp = ibp = ibpNil; /* index of the breakpoint we are at (if any) */
        !           274:        if (waitReturn == -1) {
        !           275:                if (errno == EINTR) {
        !           276:                        printf("PANIC! received signal: %d????\n", vsig);
        !           277:                        /* what do we do here?? */
        !           278:                        exit(1);
        !           279:                } 
        !           280:                else {  /* some sort of error occurred */
        !           281:                        perror("cdb");
        !           282:                        exit(1);
        !           283:                } /* if */
        !           284:        } 
        !           285:        else if (vstatLo == 0) {        /* child terminated */
        !           286:                if (vstatHi != 0)
        !           287:                        printf("Process exited with %d\n", vstatHi);
        !           288:                else printf("Process terminated normally\n");
        !           289:                KillChild();    /* go bury the corpse */
        !           290:                ibp = 0;        /* small hack - causes single step to stop in cmd.c */
        !           291:        } 
        !           292:        else if ((vstatLo&0177) == 0177) {      /* child stopped */
        !           293:                sa = vmpSigSa + vsig;
        !           294:                if (sa->fNoStop) {
        !           295: #ifdef SYSIII
        !           296:                        ioctl(0, TCSETAW, &histty);
        !           297: #endif
        !           298: #ifdef BSD41
        !           299:                        stty(0, &histty);
        !           300: #endif
        !           301:                        if (!(sa->fNoReport)) {
        !           302:                                PrintSig(vsig);
        !           303:                                printf(" at %s\n", SbFAdr(lengthen(vpc), true));
        !           304:                                PrintPos(vpc, fmtProc+fmtLn+fmtPrint);
        !           305:                        } /* if */
        !           306:                        vsig = (sa->fEatSig) ? 0 : vsig;
        !           307:                        ptrace(ptResume, vpid, 1, vsig); /* continue */
        !           308:                        goto keepGoing;
        !           309:                } /* if */
        !           310:                /* NOTE: BrkOut MIGHT back up pc, depends on machine and instruction */
        !           311:                vibp = ibp = (fDoBrk) ? BrkOut(&vpc) : ibpNil;
        !           312:                if (vpc == vadrBreak) {
        !           313:                        /* we have hit the BP used for proc calls from command line */
        !           314:                        return(ibp);
        !           315:                } /* if */
        !           316:                if ( (ibp >= 0)
        !           317:                    AND (vrgBp[ibp].sbBp[0] != chNull) ) {
        !           318:                        PushCmd(vsbCmd);
        !           319:                        vsbCmd = vrgBp[ibp].sbBp;
        !           320:                } /* if */
        !           321:                if ( (vsig != SIGTRAP) /* we ALWAYS report non-break signals */
        !           322:                    OR ((ibp >= 0)      /* there is something to hear */
        !           323:                    AND (*vsbCmd != 'Q')) ) { /* and BP's want's it heard */
        !           324:                        printf("\n");  /* in case we were left in the middle of a line */
        !           325:                        PrintSig(vsig);
        !           326:                        printf(" at %s\n", SbFAdr(lengthen(vpc), true));
        !           327:                        PrintPos(vpc, fmtProc+fmtLn+fmtPrint);
        !           328:                } 
        !           329:                else if ((vsbCmd != sbNil) AND (*vsbCmd == 'Q')) {
        !           330:                        PrintPos(vpc, fmtNil);
        !           331:                } /* if */
        !           332:                vsig = (sa->fEatSig) ? 0 : vsig;
        !           333:        } 
        !           334:        else if ((vstat & 0177) != 0177) {  /* terminated on signal */
        !           335:                if (vstat & 0177)
        !           336:                        PrintSig(vstat&0177);
        !           337:                if (vstat & 0200) {
        !           338:                        printf(" (core dumped)");
        !           339:                        close(vfnCore);
        !           340:                        InitCorefile("core");
        !           341:                } /* if */
        !           342:                printf(" at %s\n", SbFAdr(lengthen(vpc), true));
        !           343:                PrintPos(vpc, fmtProc+fmtLn+fmtPrint);
        !           344:                vpid = pidNil;
        !           345:        } /* if */
        !           346:        return(ibp);
        !           347: } /* IbpFWait */
        !           348: 
        !           349: 
        !           350: /* I B P   F   R U N */
        !           351: 
        !           352: export int IbpFRun(pt)
        !           353: int    pt;
        !           354: {
        !           355:        int             ibp;
        !           356:        ADRT    pcOld;
        !           357: 
        !           358:        if (vpid == pidNil)
        !           359:                UError("No process");
        !           360: 
        !           361:        if ((vfRunAssert)
        !           362:            AND (vas == asActive)
        !           363:            AND (viadMac > 0)
        !           364:            AND (pt != ptSingle)) {
        !           365:                /* do the assertions */
        !           366:                if (FDoAssert(pt)) /* this will change vas and single step the child */
        !           367:                        return(ibpNil); /* an assertion came up true */
        !           368:                if (vpid == pidNil)
        !           369:                        return(ibpNil); /* the child died during assertions */
        !           370:                if (vibp != ibpNil)
        !           371:                        return(vibp);
        !           372:        } /* if */
        !           373: 
        !           374:        /* hit the GO button */
        !           375: 
        !           376:        do {            /* loop allows for bp's that say 'continue' */
        !           377:                /* if we are at a breakpoint, single step over it, then install it */
        !           378:                if (IbpFBrkIn(vpc) != ibpNil) {
        !           379:                        PutState();
        !           380:                        pcOld = vpc;
        !           381:                        while (pcOld == vpc) {
        !           382:                                ptrace(ptSingle, vpid, 1, vsig);
        !           383:                                ibp = IbpFWait(false);
        !           384:                        } /* while */
        !           385:                        if (pt == ptSingle)
        !           386:                                return(ibp); /* we have already single stepped it for them */
        !           387:                        /* full steam ahead */
        !           388:                        IbpFBrkIn(adrNil); /* put in bp's */
        !           389:                } /* if */
        !           390: 
        !           391:                PutState();
        !           392: #ifdef SYSIII
        !           393:                ioctl(0, TCSETAW, &histty);
        !           394: #endif
        !           395: #ifdef BSD41
        !           396:                stty(0, &histty);
        !           397: #endif
        !           398:                errno = 0;
        !           399:                ptrace(pt, vpid, 1, vsig);      /* start child with signal `sig' */
        !           400:                ibp = IbpFWait(true);
        !           401:        } 
        !           402:        while (ibp == ibpContinue);
        !           403:        return(ibp);
        !           404: } /* IbpFRun */
        !           405: 
        !           406: 
        !           407: /* I B P   F   N E W   C H I L D */
        !           408: 
        !           409: export int IbpFNewChild(sbArgs)
        !           410: char   *sbArgs;
        !           411: {
        !           412:        int             sig, i, ibp;
        !           413:        FLAGT   fMaster;
        !           414: 
        !           415:        KillChild(); /* in case there is already one out there */
        !           416: 
        !           417: #ifdef SYSIII
        !           418:        ioctl(0, TCGETA, &histty);      /* to start with, he is the same as me */
        !           419:        ioctl(0, TCGETA, &mytty);       /* save my stuff */
        !           420: #endif
        !           421: #ifdef BSD41
        !           422:        gtty(0, &histty);  /* to start with, he is the same as me */
        !           423:        gtty(0, &mytty);        /* save my stuff */
        !           424: #endif
        !           425: 
        !           426:        if (sbArgs == sbNil) {
        !           427:                *vsbArgsChild = chNull;         /* this comes from the R command */
        !           428:        } 
        !           429:        else {
        !           430:                fMaster = (sbArgs == vsbCmd);   /* this is the normal command line */
        !           431:                while (*sbArgs == ' ' OR *sbArgs == '\011')
        !           432:                        sbArgs++;       /* eat leading white space */
        !           433:                if (*sbArgs != chNull) {
        !           434:                        strcpy(vsbArgsChild, sbArgs);
        !           435:                        for (i=strlen(sbArgs); i<cbArgsMax;     i++)
        !           436:                                vsbArgsChild[i] = chNull;
        !           437:                        /* fixes obscure bug, don't ask why...... */
        !           438:                        if (fMaster) {
        !           439:                                /* eat it - this way we don't
        !           440:                                                 * try to execute the arguments to the child
        !           441:                                                 * as debugger commands
        !           442:                                                 */
        !           443:                                vsbCmd = sbNil;
        !           444:                        } /* if */
        !           445:                } /* if */
        !           446:        } /* if */
        !           447: 
        !           448:        close(vfnSym);  /* in case it is PURE or SPLIT I&D */
        !           449:        if ((vpid = fork()) == 0) {
        !           450:                for (sig=1; sig<NSIG; sig++)
        !           451:                        signal(sig, SIG_DFL);   /* start out with default response */
        !           452:                DoArgs(vsbSymfile, vsbArgsChild, argvChild, true);
        !           453:                ptrace(ptChild, 0, 0, 0); /* Hi, Mom! */
        !           454: #ifdef REGULUS
        !           455: #define flags 04+010+020       /* overlay + set trace + environment present */
        !           456:                maketask(vsbSymfile, flags, 0, argvChild, venvpParent);
        !           457: #else
        !           458:                execvp(vsbSymfile, argvChild);
        !           459: #endif
        !           460:                /* if we get here, exec failed */
        !           461:                perror("could not startup");
        !           462:                exit(1);
        !           463:        } /* if */
        !           464: 
        !           465:        /* should only get here if parent */
        !           466:        printf("running '%s %s'\n", vsbSymfile, vsbArgsChild);
        !           467:        IbpFWait(false);
        !           468:        /* it is now safe to open symfile again */
        !           469: /* printf("Opening file %s\n", vsbSymfile); */
        !           470:        vfnSym = open(vsbSymfile, O_RDONLY);
        !           471:        if (vfnSym < 0) {
        !           472:                perror(vsbSymfile);
        !           473:                exit(1);
        !           474:        } /* if */
        !           475:        IbpFAdr(vadrStart, 0, sbNil); /* at first instruction */
        !           476:        vfRunAssert = false;  /* we don't want assertions during initialization */
        !           477:        ibp = IbpFRun(ptResume);
        !           478:        vfRunAssert = true;
        !           479:        return(ibp);
        !           480: } /* IbpFNewChild */
        !           481: 
        !           482: 
        !           483: /* K I L L   C H I L D */
        !           484: 
        !           485: export void KillChild()
        !           486: {
        !           487:        if (vpid != pidNil) {
        !           488:                ptrace(ptTerm, vpid, 0, 0);
        !           489:        }
        !           490:        vpid = pidNil;
        !           491:        vpc = adrNil;
        !           492:        vsig = 0;
        !           493:        vfp = 0;
        !           494:        if(vfnCore != fnNil) {
        !           495:                GetState();     /* refresh from the core file */
        !           496:                vpc -= 2;       /* so we have true address of error */
        !           497:        } /* if */
        !           498: } /* KillChild */
        !           499: 
        !           500: 
        !           501: /* G O T O   L N */
        !           502: 
        !           503: export void GotoLn(ln)
        !           504: int    ln;
        !           505: {
        !           506:        ADRT    adr;
        !           507: 
        !           508:        adr = AdrFIfdLn(vifd, ln);
        !           509:        if (IpdFAdr(adr) != IpdFAdr(vpc))
        !           510:                UError("You can't goto a line outside of the current procedure");
        !           511: 
        !           512:        /* if I can figure it out, it would be nice to be able to unwind the
        !           513:             * stack.  We can get the pc, fp, and ap, but the sp seems to be unknown,
        !           514:             * plus the old register values.  We might be able to 'goto' each
        !           515:             * procedure end, return up the stack, and keep doing that until we
        !           516:             * get there, but this is involved.  Maybe if someone asks REAL nicely....
        !           517:             */
        !           518:        PutReg(upc, adr);
        !           519: } /* GotoAdr */
        !           520: 
        !           521: 
        !           522: /* I N I T   S A */
        !           523: 
        !           524: export void InitSa()
        !           525: {
        !           526:        /* the 'Q' option shuts up the printout of the signal settings */
        !           527:        SaMaintain(SIGALRM, "srQ"); /* we don't stop, report or eat */
        !           528:        SaMaintain(SIGKILL, "srQ");
        !           529:        SaMaintain(SIGINT, "eQ"); /* we stop, report and eat */
        !           530:        SaMaintain(SIGTRAP, "eQ"); /* we stop, report and eat */
        !           531: #ifdef BSD41
        !           532:        SaMaintain(SIGCONT, "srQ");
        !           533:        SaMaintain(SIGCHLD, "srQ");
        !           534: #endif
        !           535: } /* InitSa */
        !           536: 
        !           537: 
        !           538: /* S A  M A I N T A I N */
        !           539: 
        !           540: export void SaMaintain(sig, sbOptions)
        !           541: int    sig;
        !           542: char   *sbOptions;
        !           543: {
        !           544:        pSAR    sa;
        !           545: 
        !           546:        sa = vmpSigSa + sig;
        !           547:        /* we toggle options based on the flags:
        !           548:             * r = report,  s = stop,  e = eat signal
        !           549:             */
        !           550:        if (strchr(sbOptions, 'r'))
        !           551:                sa->fNoReport = ~sa->fNoReport;
        !           552:        if (strchr(sbOptions, 's'))
        !           553:                sa->fNoStop = ~sa->fNoStop;
        !           554:        if (strchr(sbOptions, 'e'))
        !           555:                sa->fEatSig = ~sa->fEatSig;
        !           556: 
        !           557:        if (strchr(sbOptions, 'Q') == sbNil) {
        !           558:                printf("   Stop  Eat  Report  Name\n");
        !           559:                printf("%2d  %c     %c     %c     ", sig,
        !           560:                (sa->fNoStop) ? 'F':'T',
        !           561:                (sa->fEatSig) ? 'T':'F',
        !           562:                (sa->fNoReport) ? 'F':'T');
        !           563:                PrintSig(sig);
        !           564:                printf("\n");
        !           565:        } /* if */
        !           566: } /* SaMaintain */
        !           567: 
        !           568: 
        !           569: /* L I S T   S A */
        !           570: 
        !           571: export void ListSa()
        !           572: {
        !           573:        int             sig;
        !           574:        pSAR    sa;
        !           575: 
        !           576:        printf("   Stop  Eat  Report  Name\n");
        !           577:        for (sig=1;     sig < NSIG; sig++) {
        !           578:                sa = vmpSigSa + sig;
        !           579:                printf("%2d  %c     %c     %c     ", sig,
        !           580:                (sa->fNoStop) ? 'F':'T',
        !           581:                (sa->fEatSig) ? 'T':'F',
        !           582:                (sa->fNoReport) ? 'F':'T');
        !           583:                PrintSig(sig);
        !           584:                printf("\n");
        !           585:        } /* for */
        !           586: } /* ListSa */

unix.superglobalmegacorp.com

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