Annotation of coherent/b/bin/ps/ps_b4_krnl68/ps.c, revision 1.1.1.1

1.1       root        1: static char _version[]="ps version 2.10";
                      2: /*
                      3:  *     Modifications copyright INETCO Systems Ltd.
                      4:  *
                      5:  * Print out process statuses.
                      6:  *
                      7:  * $Log:       ps.c,v $
                      8:  * Revision 1.7  92/09/18  09:42:29  bin
                      9:  * version 210 fom piggy
                     10:  * 
                     11:  * Revision 1.3  91/07/17  14:22:55  bin
                     12:  * stevesf supplied as INETCO source because previous sources are of
                     13:  * questionable origin... this one works
                     14:  * 
                     15:  * Revision 1.2        89/06/12  15:15:22      src
                     16:  * Bug:        A directory at the end of the '/dev' directory would cause 'ps'
                     17:  *     to crash with the message "Cannot open <dir> in /dev".
                     18:  * Fix:        A stat was being done without the return code being checked. (ART)
                     19:  * 
                     20:  * Revision 1.1        89/06/12  14:42:24      src
                     21:  * Initial revision
                     22:  * 
                     23:  * 88/02/15    Allan Cornish   /usr/src/cmd/cmd/ps.c
                     24:  * Kernel processes are now displayed regardless of -ax flags.
                     25:  *
                     26:  * 87/11/25    Allan Cornish   /usr/src/cmd/cmd/ps.c
                     27:  * Debug flag now -D.  Drivers now displayed by -d flag.
                     28:  *
                     29:  * 87/11/12    Allan Cornish   /usr/src/cmd/cmd/ps.c
                     30:  * Modified to support Coherent 9.0 [protected mode] segmentation.
                     31:  *
                     32:  * 87/10/20    Allan Cornish   /usr/src/cmd/cmd/ps.c
                     33:  * Now extracts cmd name from u_comm field in uproc struct for kernel procs.
                     34:  * Kernel processes only displayed if -d [debug] flag given.
                     35:  *
                     36:  * 87/09/28    Phil Selby      /usr/src/cmd/cmd/ps.c
                     37:  * Altered so that the terminal name rather than major and minor
                     38:  * device number is printed out
                     39:  *
                     40:  * 84/08/21    Rec
                     41:  * Added gflag for group identification.
                     42:  *
                     43:  * 84/07/16    Lauren Weinstein
                     44:  * Initial version.
                     45:  */
                     46: 
                     47: #include <sys/coherent.h>
                     48: #include <sys/param.h>
                     49: #include <sys/proc.h>
                     50: #include <sys/sched.h>
                     51: #include <dirent.h>
                     52: #include <sys/seg.h>
                     53: #include <sys/stat.h>
                     54: #include <sys/uproc.h>
                     55: #include <sys/mmu.h>
                     56: #include <signal.h>
                     57: #include <access.h>
                     58: #include <fcntl.h>
                     59: #include <stdio.h>
                     60: #include <ctype.h>
                     61: #include <coff.h>
                     62: #include <pwd.h>
                     63: 
                     64: /*
                     65:  * This is a kludge for the i8086 only and will be
                     66:  * made to disappear when the segmentation (jproto)
                     67:  * is thrown away.
                     68: #undef SISTACK
                     69: #define        SISTACK SIPDATA
                     70:  */
                     71: 
                     72: /*
                     73:  *     Terminal information stored in memory for use by ps in TTY field
                     74:  */
                     75: 
                     76: struct handle {
                     77:        dev_t   dnum;           /* device number */
                     78:        char dname[DIRSIZ];     /* device name */
                     79:        struct handle *nptr;    /* pointer to next */
                     80: } *fptr, *lptr;
                     81: 
                     82: /*
                     83:  * Maximum sizes.
                     84:  */
                     85: #define ARGSIZE        512
                     86: 
                     87: /*
                     88:  * Functions to see if a pointer is in alloc space and to map a
                     89:  * pointer from alloca space to this process.
                     90:  */
                     91: #define map(p)         (&(allp[(char *)(p) - (char *) callocp.sr_base]))
                     92: 
                     93: /*
                     94:  * For easy referencing.
                     95:  */
                     96: #define NUM_SYMS       7       /* Number of symbols to look up.  */
                     97: #define        aprocq          nl[0].n_value
                     98: #define        autime          nl[1].n_value
                     99: #define astime         nl[2].n_value
                    100: #define aallocp                nl[3].n_value
                    101: #define        aend            nl[4].n_value
                    102: #define        asysmem         nl[5].n_value
                    103: #define        au              nl[6].n_value
                    104: 
                    105: #define TRUE   (1==1)
                    106: #define FALSE  (1==2)
                    107: #define LESSER(a, b)   ((a < b)?a:b)
                    108: 
                    109: /*
                    110:  * Defines for referencing page tables.
                    111:  */
                    112: #define BPCSHIFT       12      /* Shift this many to convert bytes to clicks.  */
                    113: #define ONE_CLICK      4096    /* Bytes in a click.  */
                    114: #define CLICK_OFFSET   0x00000fffL     /* Bits in virtual address indexing into page.  */
                    115: #define PT_CLICK_ADDR  0xfffff000L     /* Bits in pte pointing at the page.  */
                    116: #define PT_PRESENT(entry)  (0x01 == (entry & 0x01))    /* Is the page for
                    117:                                                         * this pte present? 
                    118:                                                         */
                    119: /*
                    120:  * This is the address of the start of the U area segment.  This
                    121:  * should probably be extracted somehow from an include file.
                    122:  * It can be derived with much pain from the s_vmem field in the seg
                    123:  * struct from the U area segment.
                    124:  */
                    125: #define USEG_BASE      0xfffff000
                    126: 
                    127: /*
                    128:  * Variables.
                    129:  */
                    130: int    aflag;                          /* All processes */
                    131: int    dflag;                          /* Driver flag */
                    132: int    dbflag;                         /* Debug flag */
                    133: int    fflag;                          /* Print out all fields */
                    134: int    gflag;                          /* Print out process groups */
                    135: int    lflag;                          /* Long format */
                    136: int    mflag;                          /* Print scheduling values */
                    137: int    nflag;                          /* No header */
                    138: int    rflag;                          /* Print out real sizes */
                    139: int    tflag;                          /* Print times */
                    140: int    wflag;                          /* Wide format */
                    141: int    xflag;                          /* Get special processes */
                    142: int    Pflag;                          /* UNDOCUMENTED: ignore present bit.  */
                    143: dev_t  ttdev;                          /* Terminal device */
                    144: 
                    145: /*
                    146:  * Table for namelist.
                    147:  */
                    148: SYMENT nl[NUM_SYMS];
                    149: 
                    150: /*
                    151:  * Symbols.
                    152:  */
                    153: char    *allp;                         /* Pointer to alloc space */
                    154: char    *kfile;                        /* Kernel data memory file */
                    155: char    *nfile;                        /* Namelist file */
                    156: char    *mfile;                        /* Memory file */
                    157: char    *dfile;                        /* Swap file */
                    158: char    argp[ARGSIZE];                 /* Arguments */
                    159: int     kfd;                           /* Kernel memory file descriptor */
                    160: int     mfd;                           /* Memory file descriptor */
                    161: int     dfd;                           /* Swap file descriptor */
                    162: struct  uproc u;                       /* User process area */
                    163: unsigned cutime;                       /* Unsigned time */
                    164: PROC    cprocq;                        /* Process queue header */
                    165: SR      callocp;                       /* Size of alloc area */
                    166: SYSMEM  sysmem;                        /* Useful system-memory info.
                    167:                                         * This variable MUST be called
                    168:                                         * "sysmem" for the MAPIO() macro.
                    169:                                         */
                    170: char *malloc();
                    171: char *uname();
                    172: unsigned cval();
                    173: cseg_t pt_index();
                    174: char *pick_nfile();
                    175: 
                    176: main(argc, argv)
                    177:        int argc;
                    178:        char *argv[];
                    179: {
                    180:        register int i;
                    181:        register char *cp;
                    182: 
                    183: #if 0
                    184: fprintf(stderr, "initialise()\n");     /* DEBUG */
                    185: #endif /* 0 */
                    186:        initialise();
                    187: #if 0
                    188: fprintf(stderr, "parse args()\n");     /* DEBUG */
                    189: #endif /* 0 */
                    190:        for (i=1; i<argc; i++) {
                    191:                for (cp=&argv[i][0]; *cp; cp++) {
                    192:                        switch (*cp) {
                    193:                        case '-':
                    194:                                continue;
                    195:                        case 'a':
                    196:                                aflag++;
                    197:                                continue;
                    198:                        case 'c':
                    199:                                if (++i >= argc)
                    200:                                        usage();
                    201:                                nfile = argv[i];
                    202:                                continue;
                    203:                        case 'd':
                    204:                                dflag++;
                    205:                                continue;
                    206:                        case 'D':
                    207:                                dbflag++;
                    208:                                continue;
                    209:                        case 'f':
                    210:                                fflag++;
                    211:                                continue;
                    212:                        case 'g':
                    213:                                gflag++;
                    214:                                continue;
                    215:                        case 'k':
                    216:                                if (++i >= argc)
                    217:                                        usage();
                    218:                                mfile = argv[i];
                    219:                                continue;
                    220:                        case 'l':
                    221:                                lflag++;
                    222:                                continue;
                    223:                        case 'm':
                    224:                                mflag++;
                    225:                                continue;
                    226:                        case 'n':
                    227:                                nflag++;
                    228:                                continue;
                    229:                        case 'P':
                    230:                                Pflag++;
                    231:                                continue;
                    232:                        case 'r':
                    233:                                rflag++;
                    234:                                continue;
                    235:                        case 't':
                    236:                                tflag++;
                    237:                                continue;
                    238:                        case 'w':
                    239:                                wflag++;
                    240:                                continue;
                    241:                        case 'x':
                    242:                                xflag++;
                    243:                                continue;
                    244:                        default:
                    245:                                usage();
                    246:                        }
                    247:                }
                    248:        }
                    249: 
                    250: #if 0
                    251: fprintf(stderr, "execute()\n");        /* DEBUG */
                    252: #endif /* 0 */
                    253:        execute();
                    254: 
                    255: #if 0
                    256: fprintf(stderr, "exit(0)\n");  /* DEBUG */
                    257: #endif /* 0 */
                    258:        exit(0);
                    259: }
                    260: 
                    261: /*
                    262:  * Initialise.
                    263:  */
                    264: initialise()
                    265: {
                    266:        register char *cp;
                    267: 
                    268:        aflag = 0;
                    269:        gflag = 0;
                    270:        lflag = 0;
                    271:        mflag = 0;
                    272:        nflag = 0;
                    273:        Pflag = 0;
                    274:        xflag = 0;
                    275:        nfile = pick_nfile();
                    276:        kfile = "/dev/kmem";
                    277:        mfile = "/dev/mem";
                    278:        dfile = "/dev/swap";
                    279:        if ((cp=malloc(BUFSIZ)) != NULL)
                    280:                setbuf(stdout, cp);
                    281: 
                    282:        /* Initialise the request for coffnlist().  */
                    283:        strcpy(nl[0]._n._n_name, "procq");
                    284:        nl[0].n_type = -1;
                    285:        strcpy(nl[1]._n._n_name, "utimer");
                    286:        nl[1].n_type = -1;
                    287:        strcpy(nl[2]._n._n_name, "stimer");
                    288:        nl[2].n_type = -1;
                    289:        strcpy(nl[3]._n._n_name, "allocp");
                    290:        nl[3].n_type = -1;
                    291:        strcpy(nl[4]._n._n_name, "end");
                    292:        nl[4].n_type = -1;
                    293:        strcpy(nl[5]._n._n_name, "sysmem");
                    294:        nl[5].n_type = -1;
                    295:        strcpy(nl[6]._n._n_name, "u");
                    296:        nl[6].n_type = -1;
                    297: 
                    298: }
                    299: 
                    300: /*
                    301:  * Print out usage.
                    302:  */
                    303: usage()
                    304: {
                    305:        panic("Usage: ps [-][acdfgklmnrtwx]");
                    306: }
                    307: 
                    308: 
                    309: /*
                    310:  * Print out information about processes.
                    311:  */
                    312: execute()
                    313: {
                    314:        int fd;
                    315:        int c, l;
                    316:        int loop_count;         /* Keep track of the number of entries read.  */
                    317:        register PROC *pp1, *pp2;
                    318: 
                    319: #if 0
                    320:        printf("execute()\n");
                    321:        fflush(stdout);
                    322: #endif /* 0 */
                    323: 
                    324:        /*
                    325:         * Check to see if the desired kernel exists and is accessable.
                    326:         * NB: the access() system call uses the REAL uid to check
                    327:         * permissions--it will not work here.
                    328:         */
                    329:        if (-1 == (fd = open(nfile, O_RDONLY))) {
                    330:                panic("%s is not readable or does not exist.", nfile);
                    331:        }
                    332:        close(fd);
                    333: 
                    334: #if 0
                    335: fprintf(stderr, "Extract symbol information from the kernel %s.\n", nfile);    /* DEBUG */
                    336: #endif /* 0 */
                    337:        /*
                    338:         * Extract symbol information from the kernel.
                    339:         */
                    340:        if (0 == coffnlist(nfile, nl, "", NUM_SYMS) ) {
                    341:                panic("Can not use kernel image %s.", nfile);
                    342:        }
                    343: 
                    344:        if (nl[0].n_type == -1) {
                    345:                panic("Bad namelist file %s", nfile);
                    346:        }
                    347: 
                    348: #if 0
                    349: fprintf(stderr, "Open the physical memory device.\n"); /* DEBUG */
                    350: fflush(stderr);
                    351: #endif /* 0 */
                    352:        /*
                    353:         * Open the physical memory device.
                    354:         */
                    355:        if ((mfd=open(mfile, 0)) < 0) {
                    356:                panic("Cannot open %s", mfile);
                    357:        }
                    358: 
                    359: #if 0
                    360: fprintf(stderr, "Open the virtual memory device.\n");  /* DEBUG */
                    361: fflush(stderr);
                    362: #endif /* 0 */
                    363:        /*
                    364:         * Open the virtual memory device.
                    365:         */
                    366:        if ((kfd = open(kfile, 0)) < 0) {
                    367:                panic("Cannot open %s", kfile);
                    368:        }
                    369: 
                    370:        /*
                    371:         * Open swap device if it exists
                    372:         */
                    373:        dfd = open(dfile, 0);
                    374: 
                    375: #if 0
                    376: fprintf(stderr, "Fetch the head of the process queue.\n");     /* DEBUG */
                    377: fflush(stderr);
                    378: #endif /* 0 */
                    379:        /*
                    380:         * Fetch the head of the process queue.
                    381:         */
                    382:        kread((long)aprocq, &cprocq, sizeof (cprocq));
                    383: 
                    384:        /*
                    385:         * Fetch information about system memory.
                    386:         */
                    387:        kread((long)asysmem, &sysmem, sizeof (sysmem));
                    388: 
                    389:        
                    390: 
                    391: #if 0
                    392: fprintf(stderr, "Take a snapshot of kernel memory.\n");        /* DEBUG */
                    393: fflush(stderr);
                    394: #endif /* 0 */
                    395:        /*
                    396:         * Take a snapshot of kernel memory.
                    397:         */
                    398:        kread((unsigned long)aallocp, &callocp, sizeof (callocp));
                    399: 
                    400: #if 0
                    401:        fprintf(stderr, "callocp.sr_size: %x\n", callocp.sr_size);
                    402:        fflush(stderr);
                    403: #endif /* 0 */
                    404: 
                    405:        if ((allp=malloc(callocp.sr_size)) == NULL) {
                    406:                panic( "Out of core or invalid kernel specified" );
                    407:        }
                    408: 
                    409: #if 0
                    410: fprintf(stderr, "kread(%x, %x, %x)\n", /* DEBUG */
                    411:                (unsigned long)callocp.sr_base, allp, callocp.sr_size);
                    412: fflush(stderr);
                    413: #endif /* 0 */
                    414: 
                    415:        kread((unsigned long)callocp.sr_base, allp, callocp.sr_size);
                    416: 
                    417: 
                    418: #if 0
                    419: fprintf(stderr, "Fetch the current tick time.\n");     /* DEBUG */
                    420: fflush(stderr);
                    421: #endif /* 0 */
                    422:        /*
                    423:         * Fetch the current tick time.
                    424:         */
                    425:        kread((long)autime, &cutime, sizeof (cutime));
                    426: 
                    427: #if 0
                    428: fprintf(stderr, "Find out what our controlling terminal is.\n");       /* DEBUG */
                    429: fflush(stderr);
                    430: #endif /* 0 */
                    431:        /*
                    432:         * Find out what our controlling terminal is.
                    433:         */
                    434:        settdev();
                    435: 
                    436:        fttys( "/dev"); /* load all the devices in dev */
                    437: 
                    438: #if 0
                    439: fprintf(stderr, "Calculate the length of the output line.\n"); /* DEBUG */
                    440: fflush(stderr);
                    441: #endif /* 0 */
                    442:        /*
                    443:         * Calculate the length of the output line.
                    444:         */
                    445:        l = strlen("TTY       PID");
                    446:        if (dbflag)
                    447:                l += strlen("0xffffffff ");
                    448:        if (gflag)
                    449:                l += strlen(" GROUP");
                    450:        if (lflag)
                    451:                l += strlen("  PPID      UID    K    F S     EVENT");
                    452:        if (mflag)
                    453:                l += strlen("      CVAL      SVAL       IVAL       RVAL");
                    454:        if (tflag)
                    455:                l += strlen(" UTIME STIME");
                    456:        if (nflag == 0) {
                    457:                if (dbflag)
                    458:                        printf("           ");
                    459:                printf("TTY       PID");
                    460:                if (gflag)
                    461:                        printf(" GROUP");
                    462:                if (lflag)
                    463:                        printf("  PPID      UID    K    F S      EVENT");
                    464:                if (mflag)
                    465:                        printf("      CVAL      SVAL       IVAL       RVAL");
                    466:                if (tflag)
                    467:                        printf(" UTIME STIME");
                    468:                putchar('\n');
                    469:                fflush(stdout);
                    470:        }
                    471: 
                    472: #if 0
                    473: fprintf(stderr, "Walk through the process queue printing out each entry.\n");  /* DEBUG */
                    474: fflush(stderr);
                    475: #endif /* 0 */
                    476:        /*
                    477:         * Walk through the process queue printing out each entry.
                    478:         */
                    479:        loop_count = 0; /* How many PROC entries have we seen?  */
                    480:        pp1 = &cprocq;
                    481:        while ((pp2=pp1->p_nback) != (PROC *) aprocq) {
                    482:                loop_count++;
                    483: 
                    484: #if 0
                    485: fprintf(stderr, "count: %d\n", loop_count);    /* DEBUG */
                    486: fflush(stderr);
                    487: #endif /* 0 */
                    488: 
                    489:                if (range((char *)pp2) == 0)
                    490:                        panic("Fragmented list");
                    491:                pp1 = map(pp2);
                    492: 
                    493:                /*
                    494:                 * Kernel process - display only if '-d' argument given.
                    495:                 */
                    496:                if ( pp1->p_flags & PFKERN ) {
                    497: #if 0
                    498: fprintf(stderr, "PFKERN\n");   /* DEBUG */
                    499: fflush(stderr);
                    500: #endif /* 0 */
                    501:                        if ( dflag == 0 ) {
                    502:                                continue;
                    503:                        }
                    504:                }
                    505: 
                    506:                /*
                    507:                 * Unattached process - display only if '-x' argument given.
                    508:                 */
                    509:                else if ( pp1->p_ttdev == NODEV ) {
                    510: #if 0
                    511: fprintf(stderr, "NODEV\n");    /* DEBUG */
                    512: fflush(stderr);
                    513: #endif /* 0 */
                    514:                        if ( xflag == 0 ) {
                    515:                                continue;
                    516:                        }
                    517:                }
                    518: 
                    519:                /*
                    520:                 * Attached to other terminal - display only if '-a' arg given.
                    521:                 */
                    522:                else if ( pp1->p_ttdev != ttdev ) {
                    523: #if 0
                    524: fprintf(stderr, "Other tty\n");        /* DEBUG */
                    525: fflush(stderr);
                    526: #endif /* 0 */
                    527:                        if ( aflag == 0 )
                    528:                                continue;
                    529:                }
                    530: 
                    531: #if 0
                    532: fprintf(stderr, "ASSERTION: pp1 is a proc entry we want to print.\n"); /* DEBUG */
                    533: fflush(stderr);
                    534: #endif /* 0 */
                    535:                /*
                    536:                 * ASSERTION: pp1 is a proc entry we want to print.
                    537:                 */
                    538: 
                    539:                if (dbflag)
                    540:                        printf("0x%8x ", pp2);
                    541:                ptty(pp1);
                    542:                printf(" %5d", pp1->p_pid);
                    543:                if (gflag)
                    544:                        printf(" %5d", pp1->p_group);
                    545:                if (lflag) {
                    546:                        printf(" %5d", pp1->p_ppid);
                    547:                        fflush(stdout);
                    548:                        printf(" %8.8s", uname(pp1));
                    549:                        fflush(stdout);
                    550:                        psize(pp1);
                    551:                        fflush(stdout);
                    552:                        printf(" %4o", pp1->p_flags);
                    553:                        fflush(stdout);
                    554:                        printf(" %c", c=state(pp1, pp2));
                    555:                        fflush(stdout);
                    556:                        if (c == 'S') {
                    557:                                print_event(pp1);
                    558:                        } else {
                    559:                                if (fflag)
                    560:                                        printf("          -");
                    561:                                else
                    562:                                        printf("           ");
                    563:                        }
                    564:                        fflush(stdout);
                    565:                }
                    566:                if (mflag) {
                    567:                        printf(" %9u", cval(pp1, pp2));
                    568:                        printf(" %9u", pp1->p_sval);
                    569:                        printf(" %10d", pp1->p_ival);
                    570:                        printf(" %10d", pp1->p_rval);
                    571:                }
                    572:                if (tflag) {
                    573:                        ptime(pp1->p_utime);
                    574:                        ptime(pp1->p_stime);
                    575:                }
                    576:                printf("  ");
                    577:                printl(pp1, (wflag?132:80)-l-1);
                    578: 
                    579:                putchar('\n');
                    580:                fflush(stdout);
                    581:        }
                    582:        rttys();        /* release all alloced space */
                    583: }
                    584: 
                    585: /*
                    586:  * Set our terminal device.
                    587:  */
                    588: settdev()
                    589: {
                    590:        register PROC *pp1, *pp2;
                    591:        register int p;
                    592:        int loop_count;
                    593: 
                    594:        p = getpid();
                    595:        pp1 = &cprocq;
                    596: 
                    597:        loop_count = 0; /* How many PROC entries have we seen?  */
                    598:        while ((pp2=pp1->p_nforw) != (PROC *) aprocq) {
                    599:                loop_count++;
                    600: #if 0
                    601: fprintf(stderr, "settdev() count: %d\n", loop_count);  /* DEBUG */
                    602: fflush(stderr);
                    603: #endif /* 0 */
                    604:                
                    605: #if 0
                    606: fprintf(stderr, "range():sr_base: %x < %x < sr_base + sr_size: %x\n",
                    607:                callocp.sr_base, pp2, callocp.sr_base + callocp.sr_size);       /* DEBUG */
                    608: fflush(stderr);
                    609: #endif /* 0 */
                    610:                if (range((char *)pp2) == 0)
                    611:                        break;
                    612: 
                    613: #if 0
                    614: fprintf(stderr, "About to map %x\n", pp2);     /* DEBUG */
                    615: fflush(stderr);
                    616: 
                    617: fprintf(stderr, "offset = (%x - sr_base) = %x \n",
                    618:                pp2, ((char *)pp2) - callocp.sr_base ); /* DEBUG */
                    619: fflush(stderr);
                    620: fprintf(stderr, "(allp:%x + offset): \n",
                    621:                allp, allp + ( ((char *) pp2) - ( (char *) callocp.sr_base) ) );        /* DEBUG */
                    622: fflush(stderr);
                    623: #endif /* 0 */
                    624: 
                    625:                pp1 = map(pp2);
                    626: 
                    627: #if 0
                    628: fprintf(stderr, "mapped %x to %x\n", pp2, pp1);        /* DEBUG */
                    629: fflush(stderr);
                    630: #endif /* 0 */
                    631:                if (pp1->p_pid == p) {
                    632:                        ttdev = pp1->p_ttdev;
                    633:                        return;
                    634:                }
                    635:        }
                    636:        ttdev = NODEV;
                    637: }
                    638: 
                    639: /*
                    640:  *     Finds all special files in the specified directory (e.g. /dev)
                    641:  */
                    642: 
                    643: fttys( dirname)
                    644: 
                    645: char *dirname;
                    646: 
                    647: {
                    648:        int filein;             /* directory file descriptor */
                    649:        struct stat sbuf;       /* stat structure */
                    650:        struct direct dbuf;     /* directory buffer structure */
                    651:        
                    652:        /* move to the appropriate directory and open file for reading */
                    653:        
                    654:        chdir( dirname );
                    655: 
                    656:        if( ( filein = open( ".", 0) ) < 0 ) {
                    657:                fprintf( stderr, "Cannot open '%s' in /dev\n", dirname );
                    658:                exit( 1 );
                    659:        }
                    660: 
                    661:        read( filein, &dbuf, sizeof(dbuf) );    /* read . */
                    662:        read( filein, &dbuf, sizeof(dbuf) );    /* read .. */
                    663: 
                    664:        while( read( filein, &dbuf, sizeof(dbuf) ) ) {
                    665:                if( stat( dbuf.d_name, &sbuf ) < 0 )
                    666:                        continue;
                    667: 
                    668:                if( sbuf.st_mode & S_IFCHR )
                    669:                        addname( dbuf.d_name, sbuf.st_rdev );
                    670: 
                    671:                else if( sbuf.st_mode & S_IFDIR )
                    672:                        fttys( dbuf.d_name );
                    673:        }
                    674: 
                    675:        close( filein );
                    676:        chdir( ".." );
                    677: }
                    678: 
                    679: /*
                    680:  *     Adds a name and device to the master list of ttys.
                    681:  */
                    682: 
                    683: addname( devname, devnum )
                    684:        char *devname;
                    685:        dev_t devnum;
                    686: {
                    687:        extern struct handle *fptr;
                    688:        extern struct handle *lptr;
                    689:        
                    690:        if( fptr == (struct handle *) NULL ) {
                    691:                if( (fptr=(struct handle *) malloc( sizeof(struct handle))) ==
                    692:                                (struct handle *) NULL ) {
                    693:                        fprintf( stderr, "Out of memory\n");
                    694:                        exit( 1 );
                    695:                }
                    696: 
                    697:                fptr->nptr = (struct handle *) NULL;
                    698:                strcpy( fptr->dname, devname);
                    699:                fptr->dnum = devnum;
                    700:        }
                    701: 
                    702:        else {
                    703:                lptr = fptr;
                    704: 
                    705:                while( ( lptr->nptr != (struct handle *) NULL ) &&
                    706:                        ( lptr->dnum != devnum ) ) lptr = lptr->nptr;
                    707: 
                    708:                if( lptr->dnum == devnum )
                    709:                        return;
                    710: 
                    711:                if( (lptr->nptr=(struct handle *)malloc(sizeof(struct handle)))
                    712:                                == (struct handle *) NULL ) {
                    713:                        fprintf( stderr, "Out of memory\n");
                    714:                        exit( 1 );
                    715:                }
                    716: 
                    717:                lptr = lptr->nptr;
                    718:                lptr->nptr = (struct handle *) NULL;
                    719:                strcpy( lptr->dname, devname);
                    720:                lptr->dnum = devnum;
                    721:        }
                    722: }
                    723: 
                    724: /*
                    725:  *     Release allocated space on exit (default action anyway)
                    726:  */
                    727: 
                    728: rttys()
                    729: {
                    730:        /* release allocated space */
                    731:        
                    732:        lptr = fptr;
                    733:        while( lptr->nptr != (struct handle *) NULL ) {
                    734:                fptr = lptr;
                    735:                lptr = fptr->nptr;
                    736:                free( fptr);
                    737:        }
                    738:        free( lptr);
                    739: }
                    740: 
                    741: /*
                    742:  *     Print the controlling terminal name.  If not found it prints the
                    743:  *     major and minor device numbers.  If no controlling terminal on the
                    744:  *     process then '--------' is printed.
                    745:  */
                    746: 
                    747: ptty( pp )
                    748:        register PROC *pp;
                    749: {
                    750:        register dev_t d;
                    751: 
                    752:        /* when supplied with a device number, look for the name
                    753:           of the special file from the dev directory */
                    754:           
                    755:        if( ((dev_t)( d = pp->p_ttdev )) == NODEV ) {
                    756:                printf( "-------");
                    757:                return;
                    758:        }
                    759: 
                    760:        lptr = fptr;
                    761:        while( lptr->nptr != (struct handle *) NULL ) {
                    762:                if( lptr->dnum == d ) {
                    763:                        printf( "%-7.7s", lptr->dname);
                    764:                        return;
                    765:                }
                    766:                lptr = lptr->nptr;
                    767:        }
                    768:        if( lptr->dnum == d ) {
                    769:                printf( "%-7.7s", lptr->dname);
                    770:                return;
                    771:        }
                    772:        printf( "%3d %3d", major( d ), minor( d ) );
                    773:        return;
                    774: }
                    775: 
                    776: /*
                    777:  * Given a process, return it's user name.
                    778:  */
                    779: char *
                    780: uname(pp)
                    781:        register PROC *pp;
                    782: {
                    783:        static char name[8];
                    784:        register struct passwd *pwp;
                    785: 
                    786:        if ((pwp=getpwuid(pp->p_ruid)) != NULL)
                    787:                return (pwp->pw_name);
                    788:        sprintf(name, "%d", pp->p_ruid);
                    789:        return (name);
                    790: }
                    791: 
                    792: /*
                    793:  * Return the core value for a process.
                    794:  */
                    795: unsigned
                    796: cval(pp1, pp2)
                    797:        register PROC *pp1;
                    798:        PROC *pp2;
                    799: {
                    800:        unsigned u;
                    801:        register PROC *pp3, *pp4;
                    802: 
                    803:        if (pp1->p_state == PSSLEEP) {
                    804:                u = (cutime-pp1->p_lctim) * 1;
                    805:                if (pp1->p_cval+u > pp1->p_cval)
                    806:                        return (pp1->p_cval+u);
                    807:                return (-1);
                    808:        }
                    809:        u = 0;
                    810:        pp3 = &cprocq;
                    811:        while ((pp4=pp3->p_lforw) != (PROC *) aprocq) {
                    812:                if (range((char *)pp4) == 0)
                    813:                        break;
                    814:                pp3 = map(pp4);
                    815:                u -= pp3->p_cval;
                    816:                if (pp2 == pp4)
                    817:                        return (u);
                    818:        }
                    819:        if (pp1->p_pid == getpid())
                    820:                return (pp1->p_cval);
                    821:        return (0);
                    822: } /* cval() */
                    823: 
                    824: /*
                    825:  * Return the size in K of the given process.
                    826:  */
                    827: psize(pp)
                    828:        register PROC *pp;
                    829: {
                    830:        long len;
                    831:        register SEG *sp;
                    832:        register int n;
                    833: 
                    834:        len = 0;
                    835:        for (n=0; n<NUSEG+1; n++) {
                    836:                if (rflag == 0)
                    837:                        if (n==SIUSERP || n==SIAUXIL)
                    838:                                continue;
                    839:                if ((sp=pp->p_segp[n]) == NULL)
                    840:                        continue;
                    841:                if (range((char *)sp) == 0) {
                    842:                        printf("   ?K");
                    843:                        return;
                    844:                }
                    845:                sp = map(sp);
                    846:                len += sp->s_size;
                    847:        }
                    848:        if (len != 0)
                    849:                printf("%4ldK", len/1024);
                    850:        else {
                    851:                if (fflag)
                    852:                        printf("    -");
                    853:                else
                    854:                        printf("     ");
                    855:        }
                    856: }
                    857: 
                    858: /*
                    859:  * Get the state of the process.
                    860:  */
                    861: state(pp1, pp2)
                    862:        register PROC *pp1;
                    863:        char *pp2;
                    864: {
                    865:        register unsigned s;
                    866: 
                    867:        s = pp1->p_state;
                    868:        if (s == PSSLEEP) {
                    869:                if (pp1->p_event == pp2)
                    870:                        return ('W');
                    871:                if ((pp1->p_flags&PFSTOP) != 0)
                    872:                        return ('T');
                    873:                return ('S');
                    874:        }
                    875:        if (s == PSRUN)
                    876:                return ('R');
                    877:        if (s == PSDEAD)
                    878:                return ('Z');
                    879:        return ('?');
                    880: }
                    881: 
                    882: /*
                    883:  * Given a time in HZ, print it out.
                    884:  */
                    885: ptime(l)
                    886:        long l;
                    887: {
                    888:        register unsigned m;
                    889: 
                    890:        if ((l=(l+HZ/2)/HZ) == 0) {
                    891:                if (fflag)
                    892:                        printf("     -");
                    893:                else
                    894:                        printf("      ");
                    895:                return;
                    896:        }
                    897:        if ((m=l/60) >= 100) {
                    898:                printf("%6d", m);
                    899:                return;
                    900:        }
                    901:        printf(" %2d:%02d", m, (unsigned)l%60);
                    902: }
                    903: 
                    904: /*
                    905:  * Print out the reason for a sleep.
                    906:  */
                    907: print_event(pp)
                    908:        register PROC *pp;
                    909: {
                    910:        /* Only print the u.u_sleep field if it is non-empty.  */
                    911: 
                    912:        if (    (u_init(pp->p_segp[SIUSERP], &u) != 0) &&
                    913:                ('\0' != u.u_sleep[0]) ) {
                    914:                        printf(" %10.10s", u.u_sleep );
                    915:        } else {
                    916:                /* Otherwise, print the address we are sleeping on.  */
                    917:                printf(" 0x%08X", pp->p_event);
                    918:        }
                    919: 
                    920:        fflush(stdout);
                    921: } /* print_event() */
                    922: 
                    923: /*
                    924:  * Print out the command line of a process.
                    925:  */
                    926: printl(pp, m)
                    927:        register PROC *pp;
                    928: {
                    929:        register char *cp;
                    930:        register int c;
                    931:        register int argc;
                    932:        register int n;
                    933:        static SR *srp;
                    934: 
                    935:        if (pp->p_state == PSDEAD) {
                    936:                printf("<zombie>");
                    937:                return;
                    938:        }
                    939:        if (pp->p_pid == 0) {
                    940:                printf("<idle>");
                    941:                return;
                    942:        }
                    943: 
                    944:        if (u_init(pp->p_segp[SIUSERP], &u) == 0) {
                    945:                printf("<ghost>");
                    946:                return;
                    947:        }
                    948: 
                    949:        printf(" %.10s", u.u_comm);
                    950:        return;
                    951: 
                    952:        /*
                    953:         * Handle kernel processes.
                    954:         */
                    955:        if ( pp->p_flags & PFKERN ) {
                    956:                printf("<%.*s>",sizeof(u.u_comm), u.u_comm[0] ? u.u_comm : "");
                    957:                return;
                    958:        }
                    959: 
                    960:        if ((argc=u.u_argc) <= 0)
                    961:                return;
                    962: 
                    963:        srp = &u.u_segl[SISTACK];
                    964:        printf("segread 2 in printl\n");
                    965:        printf("u.u_argp: %x, srp->sr_base: %x\n",
                    966:                u.u_argp, srp->sr_base);
                    967:        printf("u.u_argc: %x srp->sr_size: %x\n", u.u_argc, srp->sr_size);
                    968: 
                    969:        n = segread(&u.u_segl[SISTACK], u.u_argp, argp, 64);
                    970: 
                    971:        if (n == 0) {
                    972:                fprintf(stderr, "Bad segread()\n");     /* DEBUG */
                    973:                return;
                    974:        }
                    975: 
                    976:        m -= 2;
                    977:        cp = argp;
                    978: 
                    979:        while (argc--) {
                    980:                while ((c=*cp++) != '\0') {
                    981:                        if (!isascii(c) || !isprint(c)) {
                    982: #if 0 /* Blocked out for test purposes.  */
                    983:                                return;
                    984: #else
                    985:                                putchar('.');
                    986:                                continue;
                    987: #endif /* 0 */
                    988:                        }
                    989:                        if (m-- == 0)
                    990:                                return;
                    991:                        putchar(c);
                    992:                }
                    993:                fflush(stdout);
                    994: #if 0 /* Blocked out for test purposes.  */
                    995:                if (m-- == 0)
                    996:                        return;
                    997: #endif /* 0 */
                    998:                if (argc != 0)
                    999:                        putchar(' ');
                   1000:        }
                   1001: }
                   1002: 
                   1003: 
                   1004: /*
                   1005:  * Given a segment pointer `sp', read a u area into buffer `bp'.
                   1006:  */
                   1007: u_init(sp, bp)
                   1008:        SEG *sp;
                   1009:        char *bp;
                   1010: {
                   1011: #ifdef UPROC_VERSION
                   1012:        /* Have we verrified the uproc version number?  */
                   1013:        static version_ok = FALSE;
                   1014: #endif /* UPROC_VERSION */
                   1015: 
                   1016:        register SEG *sp1;
                   1017:        long offset;
                   1018: 
                   1019: #if 0
                   1020:        printf("u_init(sp:%x, bp:%x)\n", sp, bp);
                   1021:        fflush(stdout);
                   1022: #endif /* 0 */
                   1023: 
                   1024:        if (range((char *)sp) == 0) {
                   1025:                return (0);
                   1026:        }
                   1027: 
                   1028:        sp1 = map(sp);
                   1029: 
                   1030:        /*
                   1031:         * Figure out how far into the U segment the U area is.
                   1032:         * We do this by subtracting the starting address of the
                   1033:         * U area segment from the address of u.
                   1034:         */
                   1035:        offset = au - USEG_BASE;
                   1036: 
                   1037:        /*
                   1038:         * If the process is not swapped out, read directly from
                   1039:         * main memory.  Otherwise, read from the swap device.
                   1040:         */
                   1041:        if ((sp1->s_flags&SFCORE) != 0) {
                   1042:                if (0 == pt_mread( sp1->s_vmem, offset, bp, sizeof(UPROC) )) {
                   1043:                        return (0);
                   1044:                }
                   1045:        } else if (
                   1046:            dread((long)(sp1->s_daddr*BSIZE)+offset, bp, sizeof(UPROC)) < 0
                   1047:        ){
                   1048:                        return (0);
                   1049:        }
                   1050: 
                   1051: #ifdef UPROC_VERSION
                   1052:        /*
                   1053:         * Check the version number on this U area.
                   1054:         * I.e. does this ps match this kernel?
                   1055:         */
                   1056:        if ( ((UPROC *) bp)->u_version != UPROC_VERSION ) {
                   1057:                /*
                   1058:                 * Only print the warning if we have not yet seen
                   1059:                 * a valid version number, and then only once.
                   1060:                 *
                   1061:                 * If we have seen at least one valid version number,
                   1062:                 * it probably means that this process was dying.
                   1063:                 */
                   1064:                if (!version_ok) {
                   1065:                        static int printed_once = FALSE;
                   1066:                        if (!printed_once) {
                   1067:                                fprintf( stderr,
                   1068:                                "\nps WARNING: u area version is %x, not %x.\n",
                   1069:                                ((UPROC *) bp)->u_version, UPROC_VERSION );
                   1070:                                printed_once = TRUE;
                   1071:                        }
                   1072:                }
                   1073:                return (0);
                   1074:        }
                   1075:        version_ok = TRUE;      /* We've now seen one valid version number.  */
                   1076: #endif /* UPROC_VERSION */
                   1077:                
                   1078:        return (1);
                   1079: }
                   1080: 
                   1081: 
                   1082: /*
                   1083:  * Given an open segment pointer `sr' and an offset into the segment,
                   1084:  * `s', read `n' bytes from the segment into the buffer `bp'.
                   1085:  */
                   1086: segread(sr, s, bp, n)
                   1087:        SR *sr;
                   1088:        vaddr_t s;
                   1089:        char *bp;
                   1090:        int n;
                   1091: {
                   1092:        register SEG *sp1;
                   1093:        vaddr_t offset;
                   1094: 
                   1095: #if 0
                   1096:        printf("segread(sr:%x, s:%x, bp:%x, n:%x)\n", sr, s, bp, n);
                   1097:        fflush(stdout);
                   1098: #endif /* 0 */
                   1099: 
                   1100:        if (range((char *)sr->sr_segp) == 0) {
                   1101:                return (0);
                   1102:        }
                   1103: 
                   1104:        sp1 = map(sr->sr_segp);
                   1105: 
                   1106:        /* If segment grows up... */
                   1107:        if (0 == (SFDOWN & (sp1->s_flags)) ) {
                   1108:                /* then sr_base is the bottom of the segment, */
                   1109:                offset = s - sr->sr_base;
                   1110:        } else {
                   1111:                /* otherwise sr_base is the top of the segment.  */
                   1112:                offset = s - (sr->sr_base - sr->sr_size);
                   1113:        }
                   1114: 
                   1115:        /*
                   1116:         * If the process is not swapped out, read directly from
                   1117:         * main memory.  Otherwise, read from the swap device.
                   1118:         */
                   1119:        if ((sp1->s_flags&SFCORE) != 0) {
                   1120:                if (0 == pt_mread( sp1->s_vmem, offset, bp, n )) {
                   1121:                        return (0);
                   1122:                }
                   1123:        } else if (dread( (long)sp1->s_daddr*BSIZE + s, bp, n ) < 0 ) {
                   1124:                        return( 0 );
                   1125:        }
                   1126:        return (1);
                   1127: } /* segread() */
                   1128: 
                   1129: /*
                   1130:  * Read `n' bytes into the buffer `bp' from kernel memory
                   1131:  * starting at seek position `s'.
                   1132:  */
                   1133: kread(s, bp, n)
                   1134:        long s;
                   1135:        char *bp;
                   1136:        int n;
                   1137: {
                   1138:        lseek(kfd, (long)s, 0);
                   1139:        if (read(kfd, bp, n) != n)
                   1140:                panic("Kernel memory read error");
                   1141: }
                   1142: 
                   1143: /*
                   1144:  * Read `n' bytes into the buffer `bp' from absolute memory
                   1145:  * starting at seek position `s'.
                   1146:  */
                   1147: mread(s, bp, n)
                   1148:        long s;
                   1149:        char *bp;
                   1150:        int n;
                   1151: {
                   1152:        lseek(mfd, (long)s, 0);
                   1153:        if (read(mfd, bp, n) != n)
                   1154:                panic("Memory read error");
                   1155: }
                   1156: 
                   1157: /*
                   1158:  * Read `n' bytes into the buffer `bp' from the swap file
                   1159:  * starting at seek position `s'.
                   1160:  */
                   1161: dread(s, bp, n)
                   1162:        long s;
                   1163:        char *bp;
                   1164:        int n;
                   1165: {
                   1166:        /*
                   1167:         * If swap device exists go look at it
                   1168:         */
                   1169:        if( dfd > 0 ) {
                   1170:                lseek(dfd, (long)s, 0);
                   1171: 
                   1172:                if (read(dfd, bp, n) != n)
                   1173:                        panic("Swap read error");
                   1174: 
                   1175:                return( 1 );
                   1176:        }
                   1177: 
                   1178:        return( 0 );
                   1179: }
                   1180: 
                   1181: /*
                   1182:  * Print out an error message and exit.
                   1183:  */
                   1184: panic(a1)
                   1185:        char *a1;
                   1186: {
                   1187:        fflush(stdout);
                   1188:        sleep(2);
                   1189: 
                   1190:        fprintf(stderr, "%r", &a1);
                   1191:        fprintf(stderr, "\n");
                   1192: 
                   1193:        fflush(stderr);
                   1194:        exit(1);
                   1195: }
                   1196: 
                   1197: /*
                   1198:  * Functions to see if a pointer is in alloc space and to map a
                   1199:  * pointer from alloc space to this process.
                   1200:  */
                   1201: int
                   1202: range(p)
                   1203:        char *p;
                   1204: {
                   1205:        return (p>=(char *)(callocp.sr_base) &&
                   1206:                         p<(char*)(callocp.sr_base + callocp.sr_size));
                   1207: } /* range() */
                   1208: 
                   1209: /*
                   1210:  * Read `n' bytes into the buffer `bp' from physical memory
                   1211:  * starting at seek position `s', relative to the page table 'table'.
                   1212:  *
                   1213:  * 'table' is a fraction of a 386 page table.  The upper 20 bits of the
                   1214:  * adjusted virtual address 's' form an index into the table.  The address
                   1215:  * 's' must be adjusted so that it is relative to the start of the fractional
                   1216:  * table 'table'.  'table' is fractional because COH386 does not store whole
                   1217:  * page tables for non-running processes.
                   1218:  *
                   1219:  * The entries in the table are 32 bits long (called 'pte').  The lowest bit
                   1220:  * is the present bit.  If this is 0 for ANY of the pages we are asked to
                   1221:  * read, we return 0, indicating that we have read nothing.  The upper
                   1222:  * 20 bits of this entry point in physical memory to a click.  The lower
                   1223:  * 12 bits of the virtual address 's' are used as an index into this click
                   1224:  * to find the desired data.
                   1225:  *
                   1226:  * All other bits in the page table entry are ignored by this routine.
                   1227:  *
                   1228:  * Returns 0 on failure, 1 on success.
                   1229:  */
                   1230: 
                   1231: int
                   1232: pt_mread(table, s, bp, n)
                   1233:        cseg_t *table;  /* Page table.  */
                   1234:        vaddr_t s;      /* Where to start reading.  */
                   1235:        char *bp;       /* Buffer to copy into.  */
                   1236:        int n;          /* Number of bytes to read.  */
                   1237: {
                   1238:        int to_read;            /* Number of bytes to read next.  */
                   1239:        vaddr_t page_offset;    /* How far into page to start reading.  */
                   1240:        cseg_t pt_entry;        /* Current entry from Page Table.  */
                   1241: 
                   1242: 
                   1243: #if 0
                   1244:        printf("pt_mread(table: %x, s: %x, bp: %x, n: %x)\n", table, s, bp, n);
                   1245:        fflush(stdout);
                   1246:        sleep(1);
                   1247: #endif /* 0 */
                   1248: 
                   1249:        pt_entry = pt_index(table, s>>BPCSHIFT);
                   1250: 
                   1251:        if (!Pflag && !PT_PRESENT(pt_entry)) {
                   1252: #if 0  /* If the page is not present, the proess probably died already.  */
                   1253:                static printed_once = FALSE;
                   1254:                if (!printed_once) {
                   1255:                        printf("\npage not present: %x\n", pt_entry);
                   1256:                        printed_once = TRUE;
                   1257:                }
                   1258: #endif /* 0 */
                   1259:                return(0);
                   1260:        }
                   1261:        pt_entry &= PT_CLICK_ADDR;      /* Extract Address of click.  */
                   1262:        page_offset = s & CLICK_OFFSET; /* Extract offset into click.  */
                   1263:        to_read = LESSER(n, ONE_CLICK - page_offset); /* How far to end of click?  */
                   1264:        
                   1265:        while (n > 0) {
                   1266: 
                   1267: #if 0
                   1268:                printf("pt_mread(): mread(from: %x, to: %x, for: %x))\n",
                   1269:                       pt_entry+page_offset, bp, to_read);
                   1270:                fflush(stdout);
                   1271:                sleep(1);
                   1272: #endif /* 0 */
                   1273: 
                   1274:                mread(pt_entry+page_offset, bp, to_read);
                   1275: 
                   1276:                n -= to_read;   /* How many left?  */
                   1277:                s += to_read;   /* From where?  */
                   1278:                bp += to_read;  /* To where?  */
                   1279: 
                   1280:                pt_entry = pt_index(table, s>>BPCSHIFT);
                   1281:                if (!Pflag && !PT_PRESENT(pt_entry)) {
                   1282:                        printf("partition not present: %x.\n", pt_entry);
                   1283:                        return(0);
                   1284:                }
                   1285:                pt_entry &= PT_CLICK_ADDR;      /* Extract Address of click.  */
                   1286:                page_offset = s & CLICK_OFFSET; /* Extract offset into click. */
                   1287:                to_read = LESSER(n, ONE_CLICK);
                   1288:        } /* while (n > 0) */
                   1289: 
                   1290:        return(1);
                   1291: } /* pt_mread() */
                   1292: 
                   1293: cseg_t
                   1294: pt_index(table, index)
                   1295:        cseg_t *table;
                   1296:        vaddr_t index;
                   1297: {
                   1298:        cseg_t pte;     /* The page table entry we are looking for.  */
                   1299: 
                   1300: #if 0
                   1301:        printf("pt_index(0x%x, 0x%x)\n", table, index);
                   1302:        fflush(stdout);
                   1303:        sleep(1);
                   1304: #endif /* 0 */
                   1305: 
                   1306:        kread(table+index, &pte, sizeof(cseg_t));
                   1307: 
                   1308:        return(pte);
                   1309: } /* pt_index() */

unix.superglobalmegacorp.com

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