Annotation of researchv10no/cmd/oops/oops.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)ps.c        4.13 (Berkeley) 81/07/08";
                      2: /*
                      3:  * ps; VAX 4BSD version
                      4:  */
                      5: 
                      6: #include <stdio.h>
                      7: #include <ctype.h>
                      8: #include <nlist.h>
                      9: #include <pwd.h>
                     10: #include <sys/param.h>
                     11: #include <sys/dir.h>
                     12: #include <sys/user.h>
                     13: #include <sys/proc.h>
                     14: #include <sys/pte.h>
                     15: #include <sys/vm.h>
                     16: #include <sys/text.h>
                     17: #include <sys/stat.h>
                     18: #include <math.h>
                     19: #include <sys/vlimit.h>
                     20: #include <ftw.h>
                     21: 
                     22: struct nlist nl[] = {
                     23:        { "_proc" },
                     24: #define        X_PROC          0
                     25:        { "_Usrptmap" },
                     26: #define        X_USRPTMA       1
                     27:        { "_usrpt" },
                     28: #define        X_USRPT         2
                     29:        { "_text" },
                     30: #define        X_TEXT          3
                     31:        { "_nswap" },
                     32: #define        X_NSWAP         4
                     33:        { "_maxslp" },
                     34: #define        X_MAXSLP        5
                     35:        { "_ccpu" },
                     36: #define        X_CCPU          6
                     37:        { "_ecmx" },
                     38: #define        X_ECMX          7
                     39:        { "_nproc" },
                     40: #define        X_NPROC         8
                     41:        { "_ntext" },
                     42: #define        X_NTEXT         9
                     43:        { "_hz" },
                     44: #define        X_HZ            10
                     45:        { 0 },
                     46: };
                     47: 
                     48: struct savcom {
                     49:        union {
                     50:                struct  lsav *lp;
                     51:                float   u_pctcpu;
                     52:                struct  vsav *vp;
                     53:                int     s_ssiz;
                     54:        } sun;
                     55:        struct  asav *ap;
                     56: } *savcom;
                     57: 
                     58: struct asav {
                     59:        char    *a_cmdp;
                     60:        int     a_flag;
                     61:        short   a_stat, a_uid, a_pid, a_nice, a_pri, a_slptime, a_time;
                     62:        size_t  a_size, a_rss, a_tsiz, a_txtrss;
                     63:        short   a_xccount;
                     64:        char    a_tty[DIRSIZ+1];
                     65:        dev_t   a_ttyd;
                     66:        time_t  a_cpu;
                     67:        size_t  a_maxrss;
                     68: };
                     69: 
                     70: char   *lhdr;
                     71: struct lsav {
                     72:        short   l_ppid;
                     73:        char    l_cpu;
                     74:        int     l_addr;
                     75:        caddr_t l_wchan;
                     76: };
                     77: 
                     78: char   *uhdr;
                     79: char   *shdr;
                     80: 
                     81: char   *vhdr;
                     82: struct vsav {
                     83:        u_int   v_majflt;
                     84:        size_t  v_swrss, v_txtswrss;
                     85:        float   v_pctcpu;
                     86: };
                     87: 
                     88: struct proc proc[8];           /* 8 = a few, for less syscalls */
                     89: struct proc *mproc;
                     90: struct text *text;
                     91: 
                     92: int    paduser1;               /* avoid hardware mem clobbering botch */
                     93: union {
                     94:        struct  user user;
                     95:        char    upages[UPAGES][NBPG];
                     96: } user;
                     97: #define u      user.user
                     98: int    paduser2;               /* avoid hardware mem clobbering botch */
                     99: 
                    100: #define clear(x)       ((int)x & 0xffffff)
                    101: 
                    102: int    chkpid;
                    103: int    aflg, cflg, eflg, gflg, kflg, lflg, sflg, uflg, vflg, xflg;
                    104: char   *tptr;
                    105: char   *gettty(), *getcmd(), *getname(), *savestr(), *alloc(), *state();
                    106: double pcpu(), pmem();
                    107: int    pscomp();
                    108: int    nswap, maxslp;
                    109: struct text *atext;
                    110: double ccpu;
                    111: int    ecmx;
                    112: struct pte *Usrptma, *usrpt;
                    113: int    nproc, ntext, hz;
                    114: 
                    115: struct ttys {
                    116:        char    name[DIRSIZ+1];
                    117:        dev_t   ttyd;
                    118:        struct  ttys *next;
                    119: } *allttys;
                    120: 
                    121: 
                    122: int    npr;
                    123: 
                    124: int    cmdstart;
                    125: int    twidth;
                    126: char   *kmemf, *memf, *swapf, *nlistf;
                    127: int    kmem, mem, swap;
                    128: int    rawcpu, sumcpu;
                    129: 
                    130: int    pcbpf;
                    131: int    argaddr;
                    132: extern char _sobuf[];
                    133: 
                    134: main(argc, argv)
                    135:        char **argv;
                    136: {
                    137:        register int i, j;
                    138:        register char *ap;
                    139:        int uid, pgrp;
                    140:        off_t procp;
                    141: 
                    142:        argc--, argv++;
                    143:        twidth = 80;
                    144:        setbuf(stdout, _sobuf);
                    145:        if (argc > 0) {
                    146:                ap = argv[0];
                    147:                while (*ap) switch (*ap++) {
                    148: 
                    149:                case 'C':
                    150:                        rawcpu++;
                    151:                        break;
                    152:                case 'S':
                    153:                        sumcpu++;
                    154:                        break;
                    155:                case 'a':
                    156:                        aflg++;
                    157:                        break;
                    158:                case 'c':
                    159:                        cflg = !cflg;
                    160:                        break;
                    161:                case 'e':
                    162:                        eflg++;
                    163:                        break;
                    164:                case 'g':
                    165:                        gflg++;
                    166:                        break;
                    167:                case 'k':
                    168:                        kflg++;
                    169:                        break;
                    170:                case 'l':
                    171:                        lflg++;
                    172:                        break;
                    173:                case 's':
                    174:                        sflg++;
                    175:                        break;
                    176:                case 't':
                    177:                        if (*ap)
                    178:                                tptr = ap;
                    179:                        aflg++;
                    180:                        gflg++;
                    181:                        if (*tptr == '?')
                    182:                                xflg++;
                    183:                        while (*ap)
                    184:                                ap++;
                    185:                        break;
                    186:                case 'u':
                    187:                        uflg++;
                    188:                        break;
                    189:                case 'v':
                    190:                        cflg = 1;
                    191:                        vflg++;
                    192:                        break;
                    193:                case 'w':
                    194:                        if (twidth == 80)
                    195:                                twidth = 132;
                    196:                        else
                    197:                                twidth = BUFSIZ;
                    198:                        break;
                    199:                case 'x':
                    200:                        xflg++;
                    201:                        break;
                    202:                default:
                    203:                        if (!isdigit(ap[-1]))
                    204:                                break;
                    205:                        chkpid = atoi(--ap);
                    206:                        *ap = 0;
                    207:                        aflg++;
                    208:                        xflg++;
                    209:                        break;
                    210:                }
                    211:        }
                    212:        openfiles(argc, argv);
                    213:        getkvars(argc, argv);
                    214:        getdev("/dev");
                    215:        getdev("/dev/dk");
                    216:        getdev("/dev/pt");
                    217:        uid = getuid();
                    218:        pgrp = getpgrp();
                    219:        printhdr();
                    220:        procp = getw(nl[X_PROC].n_value);
                    221:        nproc = getw(nl[X_NPROC].n_value);
                    222:        hz = getw(nl[X_HZ].n_value);
                    223:        savcom = (struct savcom *)calloc(nproc, sizeof (*savcom));
                    224:        for (i=0; i<nproc; i += 8) {
                    225:                KMlseek(kmem, (char *)procp, 0);
                    226:                j = nproc - i;
                    227:                if (j > 8)
                    228:                        j = 8;
                    229:                j *= sizeof (struct proc);
                    230:                if (read(kmem, (char *)proc, j) != j)
                    231:                        cantread("proc table", kmemf);
                    232:                procp += j;
                    233:                for (j = j / sizeof (struct proc) - 1; j >= 0; j--) {
                    234:                        mproc = &proc[j];
                    235:                        if (mproc->p_stat == 0 ||
                    236:                            mproc->p_pgrp == 0 && xflg == 0)
                    237:                                continue;
                    238: /*
                    239:                        if (tptr == 0 && gflg == 0 && xflg == 0 &&
                    240:                            mproc->p_ppid == 1 && (mproc->p_flag&SDETACH) == 0)
                    241:                                continue;
                    242: */
                    243: 
                    244:                        if(uid != mproc->p_uid && !aflg && mproc->p_pgrp != pgrp ||
                    245:                            chkpid != 0 && chkpid != mproc->p_pid)
                    246:                                continue;
                    247:                        if (vflg && gflg == 0 && xflg == 0) {
                    248:                                if (mproc->p_stat == SZOMB ||
                    249:                                    mproc->p_flag&SWEXIT)
                    250:                                        continue;
                    251:                                if (mproc->p_slptime > MAXSLP &&
                    252:                                    (mproc->p_stat == SSLEEP ||
                    253:                                     mproc->p_stat == SSTOP))
                    254:                                continue;
                    255:                        }
                    256:                        save();
                    257:                }
                    258:        }
                    259:        qsort(savcom, npr, sizeof(savcom[0]), pscomp);
                    260:        for (i=0; i<npr; i++) {
                    261:                register struct savcom *sp = &savcom[i];
                    262:                if (lflg)
                    263:                        lpr(sp);
                    264:                else if (vflg)
                    265:                        vpr(sp);
                    266:                else if (uflg)
                    267:                        upr(sp);
                    268:                else
                    269:                        spr(sp);
                    270:                if (sp->ap->a_flag & SWEXIT)
                    271:                        printf(" <exiting>");
                    272:                else if (sp->ap->a_stat == SZOMB)
                    273:                        printf(" <defunct>");
                    274:                else if (sp->ap->a_pid == 0)
                    275:                        printf(" swapper");
                    276:                else if (sp->ap->a_pid == 2)
                    277:                        printf(" pagedaemon");
                    278:                else if (sp->ap->a_pid == 3 && sp->ap->a_flag & SSYS)
                    279:                        printf(" ip input");
                    280:                else
                    281:                        printf(" %.*s", twidth - cmdstart - 2, sp->ap->a_cmdp);
                    282:                printf("\n");
                    283:        }
                    284:        exit(npr == 0);
                    285: }
                    286: 
                    287: getw(loc)
                    288:        off_t loc;
                    289: {
                    290:        long word;
                    291: 
                    292:        KMlseek(kmem, loc, 0);
                    293:        if (read(kmem, &word, sizeof (word)) != sizeof (word))
                    294:                printf("error reading kmem at %x\n", loc);
                    295:        return (word);
                    296: }
                    297: 
                    298: openfiles(argc, argv)
                    299:        char **argv;
                    300: {
                    301: 
                    302:        kmemf = "/dev/kmem";
                    303:        if (kflg)
                    304:                kmemf = argc > 1 ? argv[1] : "/vmcore";
                    305:        kmem = open(kmemf, 0);
                    306:        if (kmem < 0) {
                    307:                perror(kmemf);
                    308:                exit(1);
                    309:        }
                    310:        if (kflg)  {
                    311:                mem = kmem;
                    312:                memf = kmemf;
                    313:        } else {
                    314:                memf = "/dev/mem";
                    315:                mem = open(memf, 0);
                    316:                if (mem < 0) {
                    317:                        perror(memf);
                    318:                        exit(1);
                    319:                }
                    320:        }
                    321:        swapf = argc>3 ? argv[3]: "/dev/drum";
                    322:        swap = open(swapf, 0);
                    323:        if (swap < 0) {
                    324:                perror(swapf);
                    325:                exit(1);
                    326:        }
                    327: }
                    328: 
                    329: getkvars(argc, argv)
                    330:        char **argv;
                    331: {
                    332:        register struct nlist *nlp;
                    333: 
                    334:        nlistf = argc > 2 ? argv[2] : "/unix";
                    335:        nlist(nlistf, nl);
                    336:        if (nl[0].n_type == 0) {
                    337:                fprintf(stderr, "%s: No namelist\n", nlistf);
                    338:                exit(1);
                    339:        }
                    340:        if (kflg)
                    341:                for (nlp = nl; nlp < &nl[sizeof (nl)/sizeof (nl[0])]; nlp++)
                    342:                        nlp->n_value = clear(nlp->n_value);
                    343:        Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
                    344:        usrpt = (struct pte *)nl[X_USRPT].n_value;
                    345:        KMlseek(kmem, (long)nl[X_NSWAP].n_value, 0);
                    346:        if (read(kmem, &nswap, sizeof (nswap)) != sizeof (nswap)) {
                    347:                cantread("nswap", kmemf);
                    348:                exit(1);
                    349:        }
                    350:        KMlseek(kmem, (long)nl[X_MAXSLP].n_value, 0);
                    351:        if (read(kmem, &maxslp, sizeof (maxslp)) != sizeof (maxslp)) {
                    352:                cantread("maxslp", kmemf);
                    353:                exit(1);
                    354:        }
                    355:        KMlseek(kmem, (long)nl[X_CCPU].n_value, 0);
                    356:        if (read(kmem, &ccpu, sizeof (ccpu)) != sizeof (ccpu)) {
                    357:                cantread("ccpu", kmemf);
                    358:                exit(1);
                    359:        }
                    360:        KMlseek(kmem, (long)nl[X_ECMX].n_value, 0);
                    361:        if (read(kmem, &ecmx, sizeof (ecmx)) != sizeof (ecmx)) {
                    362:                cantread("ecmx", kmemf);
                    363:                exit(1);
                    364:        }
                    365:        if (uflg || vflg) {
                    366:                ntext = getw(nl[X_NTEXT].n_value);
                    367:                text = (struct text *)alloc(ntext * sizeof (struct text));
                    368:                if (text == 0) {
                    369:                        fprintf(stderr, "no room for text table\n");
                    370:                        exit(1);
                    371:                }
                    372:                atext = (struct text *)getw(nl[X_TEXT].n_value);
                    373:                KMlseek(kmem, (int)atext, 0);
                    374:                if (read(kmem, (char *)text, ntext * sizeof (struct text))
                    375:                    != ntext * sizeof (struct text)) {
                    376:                        cantread("text table", kmemf);
                    377:                        exit(1);
                    378:                }
                    379:        }
                    380: }
                    381: 
                    382: printhdr()
                    383: {
                    384:        char *hdr;
                    385: 
                    386:        if (sflg+lflg+vflg+uflg > 1) {
                    387:                fprintf(stderr, "ps: specify only one of s,l,v and u\n");
                    388:                exit(1);
                    389:        }
                    390:        hdr = lflg ? lhdr : (vflg ? vhdr : (uflg ? uhdr : shdr));
                    391:        if (lflg+vflg+uflg+sflg == 0)
                    392:                hdr += strlen("SSIZ ");
                    393:        cmdstart = strlen(hdr);
                    394:        printf("%s COMMAND\n", hdr);
                    395:        fflush(stdout);
                    396: }
                    397: 
                    398: cantread(what, fromwhat)
                    399:        char *what, *fromwhat;
                    400: {
                    401:        fprintf(stderr, "ps: error reading %s from %s\n", what, fromwhat);
                    402: }
                    403: 
                    404: getdev(dir)
                    405:        register char *dir;
                    406: {
                    407:        register FILE *df;
                    408:        struct direct dirent;
                    409:        register struct ttys *dp;
                    410: 
                    411:        df = fopen (dir, "r");
                    412:        if (df != NULL) {
                    413:                while (fread (&dirent, sizeof (dirent), 1, df) == 1) {
                    414:                        dp = (struct ttys *) alloc (sizeof (struct ttys));
                    415:                        strncpy(dp->name, dirent.d_name, DIRSIZ);
                    416:                        dp->ttyd = dirent.d_ino;
                    417:                        dp->next = allttys;
                    418:                        allttys = dp;
                    419:                }
                    420:                fclose (df);
                    421:        }
                    422: }
                    423: 
                    424: char *
                    425: gettty()
                    426: {
                    427:        register char *p;
                    428:        register struct ttys *dp;
                    429: 
                    430:        if (u.u_ttyino != 0) {
                    431:                for (dp = allttys; dp; dp = dp -> next) {
                    432:                        if (dp->ttyd == u.u_ttyino) {
                    433:                                p = dp->name;
                    434:                                if (p[0]=='t' && p[1]=='t' && p[2]=='y')
                    435:                                        p += 3;
                    436:                                return (p);
                    437:                        }
                    438:                }
                    439:        }
                    440:        return ("?");
                    441: }
                    442: 
                    443: save()
                    444: {
                    445:        register struct savcom *sp;
                    446:        register struct asav *ap;
                    447:        register char *cp;
                    448:        register struct text *xp;
                    449:        char *ttyp, *cmdp;
                    450: 
                    451:        if (mproc->p_stat != SZOMB && getu() == 0)
                    452:                return;
                    453:        ttyp = gettty();
                    454:        if (xflg == 0 && ttyp[0] == '?' || tptr && strcmp(tptr, ttyp))
                    455:                return;
                    456:        sp = &savcom[npr];
                    457:        cmdp = getcmd();
                    458:        if (cmdp == 0)
                    459:                return;
                    460:        sp->ap = ap = (struct asav *)alloc(sizeof (struct asav));
                    461:        sp->ap->a_cmdp = cmdp;
                    462: #define e(a,b) ap->a = mproc->b
                    463:        e(a_flag, p_flag); e(a_stat, p_stat); e(a_nice, p_nice);
                    464:        e(a_uid, p_uid); e(a_pid, p_pid); e(a_pri, p_pri);
                    465:        e(a_slptime, p_slptime); e(a_time, p_time);
                    466:        strncpy(ap->a_tty, ttyp, 5);
                    467:        if (ap->a_stat == SZOMB) {
                    468:                register struct xproc *xp = (struct xproc *)mproc;
                    469: 
                    470:                ap->a_cpu = xp->xp_vm.vm_utime + xp->xp_vm.vm_stime;
                    471:        } else {
                    472:                ap->a_size = mproc->p_dsize + mproc->p_ssize;
                    473:                e(a_rss, p_rssize); 
                    474:                ap->a_ttyd = u.u_ttyino;
                    475:                ap->a_cpu = u.u_vm.vm_utime + u.u_vm.vm_stime;
                    476:                if (sumcpu)
                    477:                        ap->a_cpu += u.u_cvm.vm_utime + u.u_cvm.vm_stime;
                    478:                if (mproc->p_textp && text) {
                    479:                        xp = &text[mproc->p_textp - atext];
                    480:                        ap->a_tsiz = xp->x_size;
                    481:                        ap->a_txtrss = xp->x_rssize;
                    482:                        ap->a_xccount = xp->x_ccount;
                    483:                }
                    484:        }
                    485: #undef e
                    486:        ap->a_cpu /= hz;
                    487:        ap->a_maxrss = mproc->p_maxrss;
                    488:        if (lflg) {
                    489:                register struct lsav *lp;
                    490: 
                    491:                sp->sun.lp = lp = (struct lsav *)alloc(sizeof (struct lsav));
                    492: #define e(a,b) lp->a = mproc->b
                    493:                e(l_ppid, p_ppid); e(l_cpu, p_cpu);
                    494:                if (ap->a_stat != SZOMB)
                    495:                        e(l_wchan, p_wchan);
                    496: #undef e
                    497:                lp->l_addr = pcbpf;
                    498:        } else if (vflg) {
                    499:                register struct vsav *vp;
                    500: 
                    501:                sp->sun.vp = vp = (struct vsav *)alloc(sizeof (struct vsav));
                    502: #define e(a,b) vp->a = mproc->b
                    503:                if (ap->a_stat != SZOMB) {
                    504:                        e(v_swrss, p_swrss);
                    505:                        vp->v_majflt = u.u_vm.vm_majflt;
                    506:                        if (mproc->p_textp)
                    507:                                vp->v_txtswrss = xp->x_swrss;
                    508:                }
                    509:                vp->v_pctcpu = pcpu();
                    510: #undef e
                    511:        } else if (uflg)
                    512:                sp->sun.u_pctcpu = pcpu();
                    513:        else if (sflg) {
                    514:                if (ap->a_stat != SZOMB) {
                    515:                        for (cp = (char *)u.u_stack;
                    516:                            cp < &user.upages[UPAGES][0]; )
                    517:                                if (*cp++)
                    518:                                        break;
                    519:                        sp->sun.s_ssiz = (&user.upages[UPAGES][0] - cp);
                    520:                }
                    521:        }
                    522:        npr++;
                    523: }
                    524: 
                    525: double
                    526: pmem(ap)
                    527:        register struct asav *ap;
                    528: {
                    529:        double fracmem;
                    530:        int szptudot;
                    531: 
                    532:        if ((ap->a_flag&SLOAD) == 0)
                    533:                fracmem = 0.0;
                    534:        else {
                    535:                szptudot = UPAGES + clrnd(ctopt(ap->a_size+ap->a_tsiz));
                    536:                fracmem = ((float)ap->a_rss+szptudot)/CLSIZE/ecmx;
                    537:                if (ap->a_xccount)
                    538:                        fracmem += ((float)ap->a_txtrss)/CLSIZE/
                    539:                            ap->a_xccount/ecmx;
                    540:        }
                    541:        return (100.0 * fracmem);
                    542: }
                    543: 
                    544: double
                    545: pcpu()
                    546: {
                    547:        time_t time;
                    548: 
                    549:        time = mproc->p_time;
                    550:        if (time == 0 || (mproc->p_flag&SLOAD) == 0)
                    551:                return (0.0);
                    552:        if (rawcpu)
                    553:                return (100.0 * mproc->p_pctcpu);
                    554:        return (100.0 * mproc->p_pctcpu / (1.0 - exp(time * log(ccpu))));
                    555: }
                    556: 
                    557: getu()
                    558: {
                    559:        struct pte *pteaddr, apte;
                    560:        int pad1;       /* avoid hardware botch */
                    561:        struct pte arguutl[UPAGES+CLSIZE];
                    562:        int pad2;       /* avoid hardware botch */
                    563:        register int i;
                    564:        int ncl, size;
                    565: 
                    566:        size = sflg ? ctob(UPAGES) : sizeof (struct user);
                    567:        if ((mproc->p_flag & SLOAD) == 0) {
                    568:                lseek(swap, ctob(mproc->p_swaddr), 0);
                    569:                if (read(swap, (char *)&user.user, size) != size) {
                    570:                        fprintf(stderr, "ps: cant read u for pid %d from %s\n",
                    571:                            mproc->p_pid, swapf);
                    572:                        return (0);
                    573:                }
                    574:                pcbpf = 0;
                    575:                argaddr = 0;
                    576:                return (1);
                    577:        }
                    578:        pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
                    579:        KMlseek(kmem, kflg ? clear(pteaddr) : (int)pteaddr, 0);
                    580:        if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
                    581:                printf("ps: cant read indir pte at %x to get u for pid %d from %s\n",
                    582:                    pteaddr, mproc->p_pid, kmemf);
                    583:                return (0);
                    584:        }
                    585:        lseek(mem,
                    586:            ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte), 0);
                    587:        if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
                    588:                printf("ps: cant read page table for u of pid %d from %s\n",
                    589:                    mproc->p_pid, memf);
                    590:                return (0);
                    591:        }
                    592:        if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
                    593:                argaddr = ctob(arguutl[0].pg_pfnum);
                    594:        else
                    595:                argaddr = 0;
                    596:        pcbpf = arguutl[CLSIZE].pg_pfnum;
                    597:        ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
                    598:        while (--ncl >= 0) {
                    599:                i = ncl * CLSIZE;
                    600:                lseek(mem, ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
                    601:                if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
                    602:                        printf("ps: cant read page %d of u of pid %d from %s\n",
                    603:                            arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
                    604:                        return(0);
                    605:                }
                    606:        }
                    607:        return (1);
                    608: }
                    609: 
                    610: char *
                    611: getcmd()
                    612: {
                    613:        char cmdbuf[BUFSIZ];
                    614:        int pad1;               /* avoid hardware botch */
                    615:        union {
                    616:                char    argc[CLSIZE*NBPG];
                    617:                int     argi[CLSIZE*NBPG/sizeof (int)];
                    618:        } argspac;
                    619:        int pad2;               /* avoid hardware botch */
                    620:        register char *cp;
                    621:        register int *ip;
                    622:        char c;
                    623:        int nbad;
                    624:        struct dblock db;
                    625: 
                    626:        if (mproc->p_stat == SZOMB || mproc->p_flag&(SSYS|SWEXIT))
                    627:                return ("");
                    628:        if (cflg) {
                    629:                strncpy(cmdbuf, u.u_comm, sizeof (u.u_comm));
                    630:                return (savestr(cmdbuf));
                    631:        }
                    632:        if ((mproc->p_flag & SLOAD) == 0 || argaddr == 0) {
                    633:                vstodb(0, CLSIZE, &u.u_smap, &db, 1);
                    634:                lseek(swap, ctob(db.db_base), 0);
                    635:                if (read(swap, (char *)&argspac, sizeof(argspac))
                    636:                    != sizeof(argspac))
                    637:                        goto bad;
                    638:        } else {
                    639:                lseek(mem, argaddr, 0);
                    640:                if (read(mem, (char *)&argspac, sizeof (argspac))
                    641:                    != sizeof (argspac))
                    642:                        goto bad;
                    643:        }
                    644:        ip = &argspac.argi[CLSIZE*NBPG/sizeof (int)];
                    645:        ip -= 2;                /* last arg word and .long 0 */
                    646:        while (*--ip)
                    647:                if (ip == argspac.argi)
                    648:                        goto retucomm;
                    649:        *(char *)ip = ' ';
                    650:        ip++;
                    651:        nbad = 0;
                    652:        for (cp = (char *)ip; cp < &argspac.argc[CLSIZE*NBPG]; cp++) {
                    653:                c = *cp & 0177;
                    654:                if (c == 0)
                    655:                        *cp = ' ';
                    656:                else if (c < ' ' || c > 0176) {
                    657:                        if (++nbad >= 5*(eflg+1)) {
                    658:                                *cp++ = ' ';
                    659:                                break;
                    660:                        }
                    661:                        *cp = '?';
                    662:                } else if (eflg == 0 && c == '=') {
                    663:                        while (*--cp != ' ')
                    664:                                if (cp <= (char *)ip)
                    665:                                        break;
                    666:                        break;
                    667:                }
                    668:        }
                    669:        *cp = 0;
                    670:        while (*--cp == ' ')
                    671:                *cp = 0;
                    672:        cp = (char *)ip;
                    673:        strncpy(cmdbuf, cp, &argspac.argc[CLSIZE*NBPG] - cp);
                    674:        if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
                    675:                strcat(cmdbuf, " (");
                    676:                strncat(cmdbuf, u.u_comm, sizeof(u.u_comm));
                    677:                strcat(cmdbuf, ")");
                    678:        }
                    679:        if (xflg == 0 && gflg == 0 && tptr == 0 && cp[0] == '-')
                    680:                return (0);
                    681:        return (savestr(cmdbuf));
                    682: 
                    683: bad:
                    684:        fprintf(stderr, "ps: error locating command name for pid %d\n",
                    685:            mproc->p_pid);
                    686: retucomm:
                    687:        strcpy(cmdbuf, " (");
                    688:        strncat(cmdbuf, u.u_comm, sizeof (u.u_comm));
                    689:        strcat(cmdbuf, ")");
                    690:        return (savestr(cmdbuf));
                    691: }
                    692: 
                    693: char   *lhdr =
                    694: "F  UID   PID  PPID  CP PRI  NI ADDR  SZ  RSS    WCHAN STAT TTY     TIME";
                    695: lpr(sp)
                    696:        struct savcom *sp;
                    697: {
                    698:        register struct asav *ap = sp->ap;
                    699:        register struct lsav *lp = sp->sun.lp;
                    700: 
                    701:        printf("%x%5d%6u%6u%4d%4d%4d%5x%4d%5d",
                    702:            ap->a_flag, ap->a_uid,
                    703:            ap->a_pid, lp->l_ppid, lp->l_cpu&0377, ap->a_pri-PZERO,
                    704:            ap->a_nice-NZERO, lp->l_addr, ap->a_size/2, ap->a_rss/2);
                    705:        printf(lp->l_wchan ? "%9x" : "         ", (int)lp->l_wchan&~0x80000000);
                    706:        printf(" %4.4s ", state(ap));
                    707:        ptty(ap->a_tty);
                    708:        ptime(ap);
                    709: }
                    710: 
                    711: ptty(tp)
                    712:        char *tp;
                    713: {
                    714: 
                    715:        printf("%-5.5s", tp);
                    716: }
                    717: 
                    718: ptime(ap)
                    719:        struct asav *ap;
                    720: {
                    721: 
                    722:        printf("%4ld:%02ld", ap->a_cpu / hz, ap->a_cpu % hz);
                    723: }
                    724: 
                    725: char   *uhdr =
                    726: "USER       PID %CPU %MEM   SZ  RSS TTY   STAT   TIME";
                    727: upr(sp)
                    728:        struct savcom *sp;
                    729: {
                    730:        register struct asav *ap = sp->ap;
                    731:        int vmsize, rmsize;
                    732: 
                    733:        vmsize = (ap->a_size + ap->a_tsiz)/2;
                    734:        rmsize = ap->a_rss/2;
                    735:        if (ap->a_xccount)
                    736:                rmsize += ap->a_txtrss/ap->a_xccount/2;
                    737:        printf("%-8.8s %5d%5.1f%5.1f%5d%5d",
                    738:            getname(ap->a_uid), ap->a_pid, sp->sun.u_pctcpu, pmem(ap),
                    739:            vmsize, rmsize);
                    740:        putchar(' ');
                    741:        ptty(ap->a_tty);
                    742:        printf(" %4.4s", state(ap));
                    743:        ptime(ap);
                    744: }
                    745: 
                    746: char *vhdr =
                    747: "  PID TTY   STAT   TIME SL RE PAGEIN SIZE  RSS  LIM TSIZ TRS %CPU %MEM";
                    748: vpr(sp)
                    749:        struct savcom *sp;
                    750: {
                    751:        register struct vsav *vp = sp->sun.vp;
                    752:        register struct asav *ap = sp->ap;
                    753: 
                    754:        printf("%5u ", ap->a_pid);
                    755:        ptty(ap->a_tty);
                    756:        printf(" %4.4s", state(ap));
                    757:        ptime(ap);
                    758:        printf("%3d%3d%7d%5d%5d",
                    759:           ap->a_slptime > 99 ? 99 : ap-> a_slptime,
                    760:           ap->a_time > 99 ? 99 : ap->a_time, vp->v_majflt,
                    761:           ap->a_size/2, ap->a_rss/2);
                    762:        if (ap->a_maxrss == (INFINITY/NBPG))
                    763:                printf("   xx");
                    764:        else
                    765:                printf("%5d", ap->a_maxrss/2);
                    766:        printf("%5d%4d%5.1f%5.1f",
                    767:           ap->a_tsiz/2, ap->a_txtrss/2, vp->v_pctcpu, pmem(ap));
                    768: }
                    769: 
                    770: char   *shdr =
                    771: "SSIZ   PID TTY   STAT   TIME";
                    772: spr(sp)
                    773:        struct savcom *sp;
                    774: {
                    775:        register struct asav *ap = sp->ap;
                    776: 
                    777:        if (sflg)
                    778:                printf("%4d ", sp->sun.s_ssiz);
                    779:        printf("%5u", ap->a_pid);
                    780:        putchar(' ');
                    781:        ptty(ap->a_tty);
                    782:        printf(" %4.4s", state(ap));
                    783:        ptime(ap);
                    784: }
                    785: 
                    786: char *
                    787: state(ap)
                    788:        register struct asav *ap;
                    789: {
                    790:        char stat, load, nice, anom;
                    791:        static char res[5];
                    792: 
                    793:        switch (ap->a_stat) {
                    794: 
                    795:        case SSTOP:
                    796:                stat = 'T';
                    797:                break;
                    798: 
                    799:        case SSLEEP:
                    800:                if (ap->a_pri >= PZERO)
                    801:                        if (ap->a_slptime >= MAXSLP)
                    802:                                stat = 'I';
                    803:                        else
                    804:                                stat = 'S';
                    805:                else if (ap->a_flag & SPAGE)
                    806:                        stat = 'P';
                    807:                else
                    808:                        stat = 'D';
                    809:                break;
                    810: 
                    811:        case SWAIT:
                    812:        case SRUN:
                    813:        case SIDL:
                    814:                stat = 'R';
                    815:                break;
                    816: 
                    817:        case SZOMB:
                    818:                stat = 'Z';
                    819:                break;
                    820: 
                    821:        default:
                    822:                stat = '?';
                    823:        }
                    824:        load = ap->a_flag & SLOAD ? (ap->a_rss>ap->a_maxrss ? '>' : ' ') : 'W';
                    825:        if (ap->a_nice < NZERO)
                    826:                nice = '<';
                    827:        else if (ap->a_nice > NZERO)
                    828:                nice = 'N';
                    829:        else
                    830:                nice = ' ';
                    831:        anom = (ap->a_flag&SUANOM) ? 'A' : ((ap->a_flag&SSEQL) ? 'S' : ' ');
                    832:        res[0] = stat; res[1] = load; res[2] = nice; res[3] = anom;
                    833:        return (res);
                    834: }
                    835: 
                    836: /*
                    837:  * Given a base/size pair in virtual swap area,
                    838:  * return a physical base/size pair which is the
                    839:  * (largest) initial, physically contiguous block.
                    840:  */
                    841: vstodb(vsbase, vssize, dmp, dbp, rev)
                    842:        register int vsbase;
                    843:        int vssize;
                    844:        struct dmap *dmp;
                    845:        register struct dblock *dbp;
                    846: {
                    847:        register int blk = DMMIN;
                    848:        register swblk_t *ip = dmp->dm_map;
                    849: 
                    850:        if (vsbase < 0 || vsbase + vssize > dmp->dm_size)
                    851:                panic("vstodb");
                    852:        while (vsbase >= blk) {
                    853:                vsbase -= blk;
                    854:                if (blk < DMMAX)
                    855:                        blk *= 2;
                    856:                ip++;
                    857:        }
                    858:        if (*ip <= 0 || *ip + blk > nswap)
                    859:                panic("vstodb *ip");
                    860:        dbp->db_size = min(vssize, blk - vsbase);
                    861:        dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
                    862: }
                    863: 
                    864: /*ARGSUSED*/
                    865: panic(cp)
                    866:        char *cp;
                    867: {
                    868: 
                    869: #ifdef DEBUG
                    870:        printf("%s\n", cp);
                    871: #endif
                    872: }
                    873: 
                    874: min(a, b)
                    875: {
                    876: 
                    877:        return (a < b ? a : b);
                    878: }
                    879: 
                    880: pscomp(s1, s2)
                    881:        struct savcom *s1, *s2;
                    882: {
                    883:        register int i;
                    884: 
                    885:        if (uflg)
                    886:                return (s2->sun.u_pctcpu > s1->sun.u_pctcpu ? 1 : -1);
                    887:        if (vflg)
                    888:                return (vsize(s2) - vsize(s1));
                    889:        i = s1->ap->a_ttyd - s2->ap->a_ttyd;
                    890:        if (i == 0)
                    891:                i = s1->ap->a_pid - s2->ap->a_pid;
                    892:        return (i);
                    893: }
                    894: 
                    895: vsize(sp)
                    896:        struct savcom *sp;
                    897: {
                    898:        register struct asav *ap = sp->ap;
                    899:        register struct vsav *vp = sp->sun.vp;
                    900:        
                    901:        if (ap->a_flag & SLOAD)
                    902:                return (ap->a_rss +
                    903:                    ap->a_txtrss / (ap->a_xccount ? ap->a_xccount : 1));
                    904:        return (vp->v_swrss + (ap->a_xccount ? 0 : vp->v_txtswrss));
                    905: }
                    906: 
                    907: #define        NMAX    8
                    908: #define        NUID    2048
                    909: 
                    910: char   names[NUID][NMAX+1];
                    911: 
                    912: /*
                    913:  * Stolen from ls...
                    914:  */
                    915: char *
                    916: getname(uid)
                    917: {
                    918:        register struct passwd *pw;
                    919:        static init;
                    920:        struct passwd *getpwent();
                    921: 
                    922:        if (uid >= 0 && uid < NUID && names[uid][0])
                    923:                return (&names[uid][0]);
                    924:        if (init == 2)
                    925:                return (0);
                    926:        if (init == 0)
                    927:                setpwent(), init = 1;
                    928:        while (pw = getpwent()) {
                    929:                if (pw->pw_uid >= NUID)
                    930:                        continue;
                    931:                if (names[pw->pw_uid][0])
                    932:                        continue;
                    933:                strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
                    934:                if (pw->pw_uid == uid)
                    935:                        return (&names[uid][0]);
                    936:        }
                    937:        init = 2;
                    938:        endpwent();
                    939:        return (0);
                    940: }
                    941: 
                    942: char   *freebase;
                    943: int    nleft;
                    944: 
                    945: char *
                    946: alloc(size)
                    947:        int size;
                    948: {
                    949:        register char *cp;
                    950:        register int i;
                    951: 
                    952:        if (size > nleft) {
                    953:                freebase = (char *)sbrk(i = size > 2048 ? size : 2048);
                    954:                if (freebase == 0) {
                    955:                        fprintf(stderr, "ps: ran out of memory\n");
                    956:                        exit(1);
                    957:                }
                    958:                nleft = i - size;
                    959:        } else
                    960:                nleft -= size;
                    961:        cp = freebase;
                    962:        for (i = size; --i >= 0; )
                    963:                *cp++ = 0;
                    964:        freebase = cp;
                    965:        return (cp - size);
                    966: }
                    967: 
                    968: char *
                    969: savestr(cp)
                    970:        char *cp;
                    971: {
                    972:        register int len;
                    973:        register char *dp;
                    974: 
                    975:        len = strlen(cp);
                    976:        dp = (char *)alloc(len+1);
                    977:        strcpy(dp, cp);
                    978:        return (dp);
                    979: }
                    980: 
                    981: KMlseek(f, a, c)
                    982: long a;
                    983: {
                    984:        if (kflg)
                    985:                a = clear(a);
                    986:        lseek(f, a, c);
                    987: }

unix.superglobalmegacorp.com

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