Annotation of 43BSDReno/bin/ps/ps.c, revision 1.1

1.1     ! root        1: /*-
        !             2:  * Copyright (c) 1990 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: char copyright[] =
        !            22: "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
        !            23:  All rights reserved.\n";
        !            24: #endif /* not lint */
        !            25: 
        !            26: #ifndef lint
        !            27: static char sccsid[] = "@(#)ps.c       5.28 (Berkeley) 6/26/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: #include <machine/pte.h>
        !            31: 
        !            32: #include <sys/param.h>
        !            33: #include <sys/ioctl.h>
        !            34: #include <sys/tty.h>
        !            35: #include <sys/user.h>
        !            36: #include <sys/proc.h>
        !            37: #include <sys/vm.h>
        !            38: #include <sys/text.h>
        !            39: #include <sys/stat.h>
        !            40: #include <sys/mbuf.h>
        !            41: #include <nlist.h>
        !            42: #include <pwd.h>
        !            43: #include <math.h>
        !            44: #include <errno.h>
        !            45: #include <stdio.h>
        !            46: #include <ctype.h>
        !            47: #include <kvm.h>
        !            48: 
        !            49: struct usave {
        !            50:        struct  proc *u_procp;
        !            51:        struct  timeval u_start;
        !            52:        struct  rusage u_ru;
        !            53:        struct  rusage u_cru;
        !            54:        short   u_cmask;
        !            55:        char    u_acflag;
        !            56: };
        !            57: 
        !            58: /*
        !            59:  * to compute offset in common structures
        !            60:  */
        !            61: #define        POFF(x)         ((int)&((struct proc *)0)->x)
        !            62: #define        EOFF(x)         ((int)&((struct eproc *)0)->x)
        !            63: #define        UOFF(x)         ((int)&((struct usave *)0)->x)
        !            64: #define        ROFF(x)         ((int)&((struct rusage *)0)->x)
        !            65: 
        !            66: enum type      { CHAR, UCHAR, SHORT, USHORT, LONG, ULONG, KPTR };
        !            67: 
        !            68: #define        UIDFMT  "u"
        !            69: #define UIDLEN 5
        !            70: #define PIDFMT "d"
        !            71: #define PIDLEN 5
        !            72: #define        USERLEN 8
        !            73: 
        !            74: int needuser, needcomm, neednlist;
        !            75: 
        !            76: int    command(), ucomm(), logname(), pvar(), evar(), uvar(), rvar(), uname(), 
        !            77:        runame(), state(), pri(), tdev(), tname(), longtname(), started(),
        !            78:        lstarted(), wchan(), vsize(), rssize(), p_rssize(), cputime(), 
        !            79:        pmem(), pcpu(), pagein(), maxrss(), tsize(), trss();
        !            80:        /**
        !            81:        utime(), stime(), ixrss(), idrss(), isrss();
        !            82:        **/
        !            83: 
        !            84: struct usave *saveuser();
        !            85: char   *saveargs();
        !            86: 
        !            87: struct var {
        !            88:        char    *name[8];       /* name(s) of variable */
        !            89:        char    *header;        /* default header */
        !            90:        int     flag;
        !            91: #define        USER    0x01    /* requires user structure */
        !            92: #define        LJUST   0x02    /* right adjust on output */
        !            93: #define        COMM    0x04    /* requires exec arguments and environment (XXX) */
        !            94: #define        NLIST   0x08    /* requires nlist to get extra variables */
        !            95:        int     (*oproc)();     /* output routine */
        !            96:        short   width;          /* printing width */
        !            97:        /*
        !            98:         * The following (optional) elements are hooks for passing information
        !            99:         * to the generic output routines: pvar, evar, uvar (those which print
        !           100:         * simple elements from well known structures: proc, eproc, usave)
        !           101:         */
        !           102:        int     off;            /* offset in structure */
        !           103:        enum    type type;      /* type of element */
        !           104:        char    *fmt;           /* printf format */
        !           105:        /*
        !           106:         * glue to link selected fields together
        !           107:         */
        !           108:        struct  var *next;
        !           109: }  var[] = {
        !           110:        {{"command", "comm", "args"}, "COMMAND", USER|LJUST|COMM, 
        !           111:                command, 16}, 
        !           112:        {{"ucomm"}, "COMMAND",  LJUST, ucomm, MAXCOMLEN},
        !           113:        {{"logname"}, "LOGNAME", LJUST, logname, MAXLOGNAME},
        !           114:        {{"flag", "f"}, "F", 0, pvar, 7, POFF(p_flag), LONG, "x"},
        !           115:        {{"uid"}, "UID", 0, pvar, UIDLEN, POFF(p_uid),USHORT, UIDFMT},
        !           116:        {{"ruid"}, "RUID", 0, pvar, UIDLEN, POFF(p_ruid), USHORT, UIDFMT},
        !           117:        {{"svuid"}, "SVUID", 0, pvar, UIDLEN, POFF(p_svuid), USHORT, UIDFMT},
        !           118:        {{"rgid"}, "RGID", 0, pvar, UIDLEN, POFF(p_rgid), USHORT, UIDFMT},
        !           119:        {{"svgid"}, "SVGID", 0, pvar, UIDLEN, POFF(p_svgid), USHORT, UIDFMT},
        !           120:        {{"pid"}, "PID", 0, pvar, PIDLEN, POFF(p_pid),SHORT, PIDFMT},
        !           121:        {{"ppid"}, "PPID", 0, pvar, PIDLEN, POFF(p_ppid), SHORT, PIDFMT},
        !           122:        {{"cp", "cpu"}, "CP", 0, pvar, 3, POFF(p_cpu), UCHAR, "d"},
        !           123:        {{"xstat"}, "XSTAT", 0, pvar, 4, POFF(p_xstat), USHORT, "x"},
        !           124:        {{"poip"}, "POIP", 0, pvar, 4, POFF(p_poip), SHORT, "d"},
        !           125:        {{"nwchan"}, "WCHAN", 0, pvar, 6, POFF(p_wchan), KPTR, "x"},
        !           126:        {{"wchan"}, "WCHAN", LJUST, wchan, 6},
        !           127:        {{"rlink"}, "RLINK", 0, pvar, 8, POFF(p_rlink), KPTR, "x"},
        !           128:        {{"ktrace", "traceflag"}, "KTRACE",
        !           129:                0, pvar, 8, POFF(p_traceflag), LONG, "x"},
        !           130:        {{"ktracep", "tracep"}, "KTRACEP",
        !           131:                0, pvar, 8, POFF(p_tracep), LONG, "x"},
        !           132:        {{"sig", "pending"}, "PENDING",
        !           133:                0, pvar, 8, POFF(p_sig), LONG, "x"},
        !           134:        {{"sigmask", "blocked"}, "BLOCKED",
        !           135:                0, pvar, 8, POFF(p_sigmask), LONG, "x"},
        !           136:        {{"sigignore", "ignored"}, "IGNORED",
        !           137:                0, pvar, 8, POFF(p_sigignore), LONG, "x"},
        !           138:        {{"sigcatch", "caught"}, "CAUGHT",
        !           139:                0, pvar, 8, POFF(p_sigcatch), LONG, "x"},
        !           140:        {{"user", "uname"}, "USER", LJUST, uname, USERLEN},
        !           141:        {{"ruser", "runame"}, "RUSER", LJUST, runame, USERLEN},
        !           142:        {{"pgid"}, "PGID", 0, evar, PIDLEN, EOFF(e_pgid), USHORT, PIDFMT},
        !           143:        {{"jobc"}, "JOBC", 0, evar, 4, EOFF(e_jobc), SHORT, "d"},
        !           144:        {{"sess", "session"}, "SESS", 0, evar, 6, EOFF(e_sess), KPTR, "x"},
        !           145:        {{"tdev", "dev"}, "TDEV", 0, tdev, 4},
        !           146:        {{"tname", "tty", "tt"}, "TT", LJUST, tname, 3},
        !           147:        {{"longtname", "longtty"}, "TT", LJUST, longtname, 8},
        !           148:        {{"tpgid"}, "TPGID", 0, evar, 4, EOFF(e_tpgid), USHORT, PIDFMT},
        !           149:        {{"tsession", "tsess"}, "TSESS", 
        !           150:                0, evar, 6, EOFF(e_tsess), KPTR, "x"},
        !           151:        {{"paddr", "procaddr"}, "PADDR",
        !           152:                0, evar, 6, EOFF(e_paddr), KPTR, "x"},
        !           153:        {{"state", "stat"}, "STAT", 0, state, 4},
        !           154:        {{"pri"}, "PRI", 0, pri, 3},
        !           155:        {{"usrpri"}, "UPR", 0, pvar, 3, POFF(p_usrpri), CHAR, "d"},
        !           156:        {{"nice", "ni"}, "NI", 0, pvar, 2, POFF(p_nice), CHAR, "d"}, 
        !           157:        {{"vsize", "vsz"}, "VSZ", 0, vsize, 5},
        !           158:        {{"rssize", "rsz"}, "RSZ", 0, rssize, 4},
        !           159:        {{"rss", "p_rss"}, "RSS", 0, p_rssize, 4},
        !           160:        {{"u_procp", "uprocp"}, "UPROCP",
        !           161:                USER, uvar, 6, UOFF(u_procp), KPTR, "x"},
        !           162:        {{"umask", "u_cmask"}, "UMASK",
        !           163:                USER, uvar, 3, UOFF(u_cmask), CHAR, "#o"},
        !           164:        {{"acflag", "acflg"}, "ACFLG",
        !           165:                USER, uvar, 3, UOFF(u_acflag), SHORT, "x"},
        !           166:        {{"start"}, "STARTED", USER|LJUST, started, 8},
        !           167:        {{"lstart"}, "STARTED", USER|LJUST, lstarted, 28},
        !           168:        {{"cputime", "time"}, "TIME", USER, cputime, 9},
        !           169:        {{"p_ru"}, "P_RU", 0, pvar, 6, POFF(p_ru), KPTR, "x"},
        !           170:        {{"pcpu", "%cpu"}, "%CPU", NLIST, pcpu, 4},
        !           171:        {{"pmem", "%mem"}, "%MEM", NLIST, pmem, 4},
        !           172:        {{"sl", "slp", "slptime"}, "SL",
        !           173:                0, pvar, 3, POFF(p_slptime), CHAR, "d"},
        !           174:        {{"re", "resident"}, "RE",
        !           175:                0, pvar, 3, POFF(p_time), CHAR, "d"},
        !           176:        {{"pagein", "majflt"}, "PAGEIN", USER, pagein, 6},
        !           177:        {{"lim", "maxrss"}, "LIM", 0, maxrss, 5},
        !           178:        {{"tsiz"}, "TSIZ", 0, tsize, 4},
        !           179:        {{"trs"}, "TRS", 0, trss, 3},
        !           180:        /***
        !           181:        {{"utime"}, "UTIME", USER, utime, 4},
        !           182:        {{"stime"}, "STIME", USER, stime, 4},
        !           183:        {{"ixrss"}, "IXRSS", USER, ixrss, 4},
        !           184:        {{"idrss"}, "IDRSS", USER, idrss, 4},
        !           185:        {{"isrss"}, "ISRSS", USER, isrss, 4},
        !           186:        ***/
        !           187:        {{"minflt"}, "MINFLT", 
        !           188:                USER, rvar, 4, ROFF(ru_minflt), LONG, "d"},
        !           189:        {{"majflt"}, "MAJFLT", 
        !           190:                USER, rvar, 4, ROFF(ru_majflt), LONG, "d"},
        !           191:        {{"nswap"}, "NSWAP",    
        !           192:                USER, rvar, 4, ROFF(ru_nswap), LONG, "d"},
        !           193:        {{"inblock", "inblk"}, "INBLK",         
        !           194:                USER, rvar, 4, ROFF(ru_inblock), LONG, "d"},
        !           195:        {{"oublock", "oublk"}, "OUBLK", 
        !           196:                USER, rvar, 4, ROFF(ru_oublock), LONG, "d"},
        !           197:        {{"msgsnd"}, "MSGSND", 
        !           198:                USER, rvar, 4, ROFF(ru_msgsnd), LONG, "d"},
        !           199:        {{"msgrcv"}, "MSGRCV", 
        !           200:                USER, rvar, 4, ROFF(ru_msgrcv), LONG, "d"},
        !           201:        {{"nsignals", "nsigs"}, "NSIGS", 
        !           202:                USER, rvar, 4, ROFF(ru_nsignals), LONG, "d"},
        !           203:        {{"nvcsw", "vcsw"}, "VCSW", 
        !           204:                USER, rvar, 5, ROFF(ru_nvcsw), LONG, "d"},
        !           205:        {{"nivcsw", "ivcsw"}, "IVCSW", 
        !           206:                USER, rvar, 5, ROFF(ru_nivcsw), LONG, "d"},
        !           207:        NULL
        !           208: };
        !           209: 
        !           210: /* 
        !           211:  * combination variables 
        !           212:  */
        !           213: struct combovar {
        !           214:        char *name;
        !           215:        char *replace;
        !           216: } combovar[] = {
        !           217:        "RUSAGE", "minflt majflt nswap inblock oublock \
        !           218:                msgsnd msgrcv nsigs nvcsw nivcsw",
        !           219:        0, 0
        !           220: };
        !           221: #define DFMT   "pid tname state cputime comm"
        !           222: #define LFMT \
        !           223:        "uid pid ppid cp pri nice vsz rss wchan state tname cputime comm"
        !           224: #define        JFMT    "user pid ppid pgid sess jobc state tname cputime comm"
        !           225: #define        SFMT    "uid pid sig sigmask sigignore sigcatch stat tname comm"
        !           226: #define        VFMT \
        !           227:        "pid tt state time sl re pagein vsz rss lim tsiz trs %cpu %mem comm"
        !           228: #define UFMT \
        !           229:        "uname pid %cpu %mem vsz rss tt state start time comm"
        !           230: 
        !           231: struct kinfo {
        !           232:        struct proc *ki_p;      /* proc structure */
        !           233:        struct eproc *ki_e;     /* extra stuff */
        !           234:        struct usave *ki_u;     /* interesting parts of user */
        !           235:        char *ki_args;          /* exec args (should be char **) */
        !           236:        char *ki_env;           /* environment (should be char **) */
        !           237: } *kinfo;
        !           238: 
        !           239: struct var *vhead, *vtail;
        !           240: int    termwidth;      /* width of screen (0 == infinity) */
        !           241: #define UNLIMITED      0
        !           242: int    totwidth;       /* calculated width of requested variables */
        !           243: int    sumrusage;
        !           244: int    rawcpu;
        !           245: int    sortby;
        !           246: #define        SORTMEM 1
        !           247: #define        SORTCPU 2
        !           248: 
        !           249: int    uid = -1;
        !           250: dev_t  ttydev = NODEV;
        !           251: int    pid = -1;
        !           252: int    all;
        !           253: int    xflg;
        !           254: int    prtheader;
        !           255: int    lineno;
        !           256: 
        !           257: /*
        !           258:  * variables retrieved via nlist
        !           259:  */
        !           260: struct nlist psnl[] = {
        !           261:        {"_ecmx"},
        !           262: #define        X_ECMX          0
        !           263:        {"_fscale"},
        !           264: #define        X_FSCALE        1
        !           265:        {"_ccpu"},
        !           266: #define        X_CCPU          2
        !           267:        {NULL}
        !           268: };
        !           269: int    fscale;
        !           270: int    ecmx;
        !           271: fixpt_t        ccpu;
        !           272: 
        !           273: #define USAGE  "ps [ -(o|O) fmt ] [ -wlvujnsaxSCLmcr ] [ -p pid ] [ -t tty ]"
        !           274: 
        !           275: main (argc, argv) 
        !           276:        char *argv[];
        !           277: {
        !           278:        extern char *optarg;
        !           279:        extern int optind;
        !           280:        int ch; 
        !           281:        register i;
        !           282:        register struct var *v;
        !           283:        register struct proc *p;
        !           284:        struct winsize ws;
        !           285:        struct kinfo_proc *kprocs;
        !           286:        int nentries;
        !           287:        int fmt = 0;
        !           288:        int pscomp();
        !           289:        int what, flag;
        !           290:        char *kludge_oldps_options();
        !           291: 
        !           292:        if ((ioctl(1, TIOCGWINSZ, &ws) == -1 && 
        !           293:             ioctl(2, TIOCGWINSZ, &ws) == -1 &&
        !           294:             ioctl(0, TIOCGWINSZ, &ws) == -1) ||
        !           295:             ws.ws_col == 0)
        !           296:                termwidth = 79;
        !           297:        else
        !           298:                termwidth = ws.ws_col - 1;
        !           299:        if (argc > 1)
        !           300:                argv[1] = kludge_oldps_options(argv[1]);
        !           301: 
        !           302:        while ((ch = getopt(argc, argv, "o:O:wlvujnsaxt:p:SCLmrhTg")) != EOF)
        !           303:                switch((char)ch) {
        !           304:                case 'o':
        !           305:                        parsefmt(optarg);
        !           306:                        fmt++;
        !           307:                        break;
        !           308:                case 'O':
        !           309:                        parsefmt("pid");
        !           310:                        parsefmt(optarg);
        !           311:                        parsefmt("state tt time command");
        !           312:                        fmt++;
        !           313:                        break;
        !           314:                case 'w':
        !           315:                        if (termwidth < 131)
        !           316:                                termwidth = 131;
        !           317:                        else
        !           318:                                termwidth = UNLIMITED;
        !           319:                        break;
        !           320:                case 'l':
        !           321:                        parsefmt(LFMT);
        !           322:                        fmt++;
        !           323:                        break;
        !           324:                case 'v':
        !           325:                        parsefmt(VFMT);
        !           326:                        sortby = SORTMEM;
        !           327:                        fmt++;
        !           328:                        break;
        !           329:                case 'u':
        !           330:                        parsefmt(UFMT);
        !           331:                        sortby = SORTCPU;
        !           332:                        fmt++;
        !           333:                        break;
        !           334:                case 'j':
        !           335:                        parsefmt(JFMT);
        !           336:                        fmt++;
        !           337:                        break;
        !           338:                case 's':
        !           339:                        parsefmt(SFMT);
        !           340:                        fmt++;
        !           341:                        break;
        !           342:                case 'T':
        !           343:                case 't': {
        !           344:                        struct stat stbuf;
        !           345:                        char *tname, *ttyname();
        !           346:                        char termname[MAXPATHLEN+1];
        !           347: 
        !           348:                        if (ch == 'T') {
        !           349:                                if ((tname = ttyname(0)) == NULL)
        !           350:                                        error("<stdin>: not a terminal");
        !           351:                        } else 
        !           352:                                tname = optarg;
        !           353:                        if (strlen(tname) == 2) {
        !           354:                                if (strcmp(tname, "co") == 0)
        !           355:                                        strcpy(termname, "/dev/console");
        !           356:                                else {
        !           357:                                        strcpy(termname, "/dev/tty");
        !           358:                                        strcat(termname, tname);
        !           359:                                }
        !           360:                        } else if (*tname != '/') {
        !           361:                                strcpy(termname, "/dev/");
        !           362:                                strcat(termname, tname);
        !           363:                        } else
        !           364:                                strcpy(termname, tname);
        !           365:                        if (stat(termname, &stbuf) == -1)
        !           366:                                syserror(termname);
        !           367:                        if ((stbuf.st_mode & S_IFMT) != S_IFCHR)
        !           368:                                error("%s: not a terminal", termname);
        !           369:                        ttydev = stbuf.st_rdev;
        !           370:                        break;
        !           371:                }
        !           372:                case 'p':
        !           373:                        pid = atoi(optarg);
        !           374:                        xflg++;
        !           375:                        break;
        !           376:                case 'S':
        !           377:                        sumrusage++;
        !           378:                        break;
        !           379:                case 'C':
        !           380:                        rawcpu++;
        !           381:                        break;
        !           382:                case 'L': {
        !           383:                        int i = 0;
        !           384:                        struct combovar *cb = &combovar[0];
        !           385:                        char *cp;
        !           386: 
        !           387:                        v = &var[0];
        !           388:                        for (;;) {
        !           389:                                if (v->name[0] != NULL) {
        !           390:                                        cp = v->name[0];
        !           391:                                        v++;
        !           392:                                } else if (cb->name != NULL) {
        !           393:                                        cp = cb->name;
        !           394:                                        cb++;
        !           395:                                } else
        !           396:                                        break;
        !           397:                                if (termwidth && 
        !           398:                                   (i += strlen(cp)+1) > termwidth)
        !           399:                                        i = strlen(cp), printf("\n");
        !           400:                                printf("%s ", cp);
        !           401:                        }
        !           402:                        printf("\n");
        !           403:                        exit(0);
        !           404:                }
        !           405:                case 'a':
        !           406:                        all++;
        !           407:                        break;
        !           408:                case 'x':
        !           409:                        xflg++;
        !           410:                        break;
        !           411:                case 'm':
        !           412:                        sortby = SORTMEM;
        !           413:                        break;
        !           414:                case 'r':
        !           415:                        sortby = SORTCPU;
        !           416:                        break;
        !           417:                case 'h':
        !           418:                        prtheader = ws.ws_row > 5 ? ws.ws_row : 22;
        !           419:                        break;
        !           420:                case 'g':
        !           421:                        break;  /* no-op */
        !           422:                case '?':
        !           423:                default:
        !           424:                        fprintf(stderr, "usage: %s\n", USAGE);
        !           425:                        exit(1);
        !           426:                }
        !           427:        argc -= optind;
        !           428:        argv += optind;
        !           429:        
        !           430:        if (*argv) {
        !           431:                char *nlistf, *memf = NULL, *swapf = NULL;
        !           432: 
        !           433:                nlistf = *argv++;
        !           434:                if (*argv) {
        !           435:                        memf = *argv++;
        !           436:                        if (*argv)
        !           437:                                swapf = *argv++;
        !           438:                }
        !           439:                if (kvm_openfiles(nlistf, memf, swapf) == -1)
        !           440:                        error("kvm_openfiles: %s", kvm_geterr());
        !           441:        }
        !           442: 
        !           443:        if (!fmt)
        !           444:                parsefmt(DFMT);
        !           445: 
        !           446:        if (!all && ttydev == NODEV && pid == -1)  /* XXX - should be cleaner */
        !           447:                uid = getuid();
        !           448: 
        !           449:        /*
        !           450:         * scan requested variables, noting what structures are needed,
        !           451:         * and adjusting header widths as appropiate.
        !           452:         */
        !           453:        scanvars();
        !           454: #ifdef notdef
        !           455:        if (sortby == SORTCPU)
        !           456:                neednlist = 1;
        !           457: #endif
        !           458:        if (neednlist)
        !           459:                donlist();
        !           460:        /*
        !           461:         * get proc list
        !           462:         */
        !           463:        if (uid != -1) {
        !           464:                what = KINFO_PROC_UID;
        !           465:                flag = uid;
        !           466:        } else if (ttydev != NODEV) {
        !           467:                what = KINFO_PROC_TTY;
        !           468:                flag = ttydev;
        !           469:        } else if (pid != -1) {
        !           470:                what = KINFO_PROC_PID;
        !           471:                flag = pid;
        !           472:        } else
        !           473:                what = KINFO_PROC_ALL;
        !           474:        /*
        !           475:         * select procs
        !           476:         */
        !           477:        if ((nentries = kvm_getprocs(what, flag)) == -1) {
        !           478:                fprintf(stderr, "ps: %s\n", kvm_geterr());
        !           479:                exit(1);
        !           480:        }
        !           481:        kinfo = (struct kinfo *)malloc(nentries * sizeof (struct kinfo));
        !           482:        if (kinfo == NULL)
        !           483:                error("out of memory");
        !           484:        i = 0;
        !           485:        while ((p = kvm_nextproc()) != NULL) {
        !           486:                kinfo[i].ki_p = p;
        !           487:                kinfo[i].ki_e = kvm_geteproc(p);
        !           488:                if (needuser)
        !           489:                        saveuser(&kinfo[i]);
        !           490:                i++;
        !           491:        }
        !           492:        nentries = i;
        !           493:        /*
        !           494:         * print header
        !           495:         */
        !           496:        printheader();
        !           497:        if (nentries == 0)
        !           498:                exit(0);
        !           499:        /*
        !           500:         * sort proc list
        !           501:         */
        !           502:        qsort(kinfo, nentries, sizeof (struct kinfo), pscomp);
        !           503:        /*
        !           504:         * for each proc, call each variable output function.
        !           505:         */
        !           506:        for (i = 0; i < nentries; i++) {
        !           507:                if (xflg == 0 && (kinfo[i].ki_e->e_tdev == NODEV ||
        !           508:                    (kinfo[i].ki_p->p_flag & SCTTY ) == 0))
        !           509:                        continue;
        !           510:                for (v = vhead; v != NULL; v = v->next) {
        !           511:                        (*v->oproc)(&kinfo[i], v);
        !           512:                        if (v->next != NULL)
        !           513:                                putchar(' ');
        !           514:                }
        !           515:                putchar('\n');
        !           516:                if (prtheader && lineno++ == prtheader-4) {
        !           517:                        putchar('\n');
        !           518:                        printheader();
        !           519:                        lineno = 0;
        !           520:                }
        !           521:        }
        !           522: 
        !           523:        exit(0);
        !           524: }
        !           525: 
        !           526: #define FMTSEP " \t,\n"
        !           527: 
        !           528: parsefmt(fmt)
        !           529:        char *fmt;
        !           530: {
        !           531:        register char *f = fmt, *cp, *hp;
        !           532:        struct var *v;
        !           533:        char *strtok(), *index();
        !           534:        char newbuf[1024], *nb = newbuf; /* XXX */
        !           535:        char *lookupcombo();
        !           536:        struct var *lookupvar();
        !           537:        
        !           538:        /*
        !           539:         * strtok is not &^%^& re-entrant, so we have
        !           540:         * only one level of expansion, looking for combo
        !           541:         * variables once here, and expanding the string
        !           542:         * before really parsing it.  With strtok_r,
        !           543:         * you would move the expansion to before the
        !           544:         * lookupvar inside the 2nd while loop with a
        !           545:         * recursive call to parsefmt.
        !           546:         */
        !           547:        while ((cp = strtok(f, FMTSEP)) != NULL) {
        !           548:                if ((hp = lookupcombo(cp)) == NULL);
        !           549:                        hp = cp;
        !           550:                if (((nb + strlen(hp)) - newbuf) >= 1024)
        !           551:                        error("format too large");
        !           552:                strcpy(nb, hp);
        !           553:                while (*nb)
        !           554:                        nb++;
        !           555:                *nb++ = ' ';
        !           556:                *nb =  '\0';
        !           557:                f = NULL;
        !           558:        }
        !           559:        f = newbuf;
        !           560:        while ((cp = strtok(f, FMTSEP)) != NULL) {
        !           561:                if (hp = index(cp, '='))
        !           562:                        *hp++ = '\0';
        !           563:                v = lookupvar(cp);
        !           564:                if (v == NULL)
        !           565:                        error("unknown variable in format: %s", cp);
        !           566:                if (v->next != NULL || vtail == v)
        !           567:                        error("can't specify a variable twice: %s", cp);
        !           568:                if (hp)
        !           569:                        v->header = hp;
        !           570:                if (vhead == NULL)
        !           571:                        vhead = vtail = v;
        !           572:                else {
        !           573:                        vtail->next = v;
        !           574:                        vtail = v;
        !           575:                }
        !           576:                f = NULL;       /* for strtok */
        !           577:        }
        !           578: 
        !           579: }
        !           580: 
        !           581: scanvars()
        !           582: {
        !           583:        register i;
        !           584:        register struct var *v;
        !           585: 
        !           586:        for (v = vhead; v != NULL; v = v->next) {
        !           587:                i = strlen(v->header);
        !           588:                if (v->width < i)
        !           589:                        v->width = i;
        !           590:                totwidth += v->width + 1;       /* +1 for space */
        !           591:                if (v->flag & USER)
        !           592:                        needuser = 1;
        !           593:                if (v->flag & COMM)
        !           594:                        needcomm = 1;
        !           595:                if (v->flag & NLIST)
        !           596:                        neednlist = 1;
        !           597:        }
        !           598:        totwidth--;
        !           599: }
        !           600: printheader()
        !           601: {
        !           602:        register struct var *v;
        !           603: 
        !           604:        for (v = vhead; v != NULL; v = v->next) {
        !           605:                if (v->flag & LJUST) {
        !           606:                        if (v->next == NULL)    /* last one */
        !           607:                                printf("%s", v->header);
        !           608:                        else
        !           609:                                printf("%-*s",v->width, v->header);
        !           610:                } else
        !           611:                        printf("%*s",v->width, v->header);
        !           612:                if (v->next != NULL)
        !           613:                        putchar(' ');
        !           614:        }
        !           615:        putchar('\n');
        !           616: }
        !           617: 
        !           618: command(k, v) 
        !           619:        struct kinfo *k;
        !           620:        struct var *v;
        !           621: {
        !           622: 
        !           623:        if (v->next == NULL) {          
        !           624:                /* last field */
        !           625:                if (termwidth == UNLIMITED)
        !           626:                        printf("%s", k->ki_args);
        !           627:                else {
        !           628:                        register left = termwidth - (totwidth - v->width);
        !           629:                        register char *cp = k->ki_args;
        !           630: 
        !           631:                        if (left < 1)   /* already wrapped, just use std width */
        !           632:                                left = v->width;
        !           633:                        while (left-- && *cp)
        !           634:                                putchar(*cp++);
        !           635:                }
        !           636:        } else
        !           637:                printf("%-*.*s", v->width, v->width, k->ki_args);
        !           638:                
        !           639: }
        !           640: 
        !           641: ucomm(k, v) 
        !           642:        struct kinfo *k;
        !           643:        struct var *v;
        !           644: {
        !           645: 
        !           646:        printf("%-*s", v->width, k->ki_p->p_comm);
        !           647: }
        !           648: 
        !           649: logname(k, v) 
        !           650:        struct kinfo *k;
        !           651:        struct var *v;
        !           652: {
        !           653: 
        !           654:        printf("%-*s", v->width, k->ki_p->p_logname);
        !           655: }
        !           656: 
        !           657: state(k, v)
        !           658:        struct kinfo *k;
        !           659:        struct var *v;
        !           660: {
        !           661:        char buf[16];
        !           662:        register char *cp = buf;
        !           663:        register struct proc *p = k->ki_p;
        !           664:        register flag = p->p_flag;
        !           665: 
        !           666:        switch (p->p_stat) {
        !           667: 
        !           668:        case SSTOP:
        !           669:                *cp = 'T';
        !           670:                break;
        !           671: 
        !           672:        case SSLEEP:
        !           673:                if (flag & SSINTR)      /* interuptable (long) */
        !           674:                        *cp = p->p_slptime >= MAXSLP ? 'I' : 'S';
        !           675:                else 
        !           676:                        *cp = (flag & SPAGE) ? 'P' : 'D';
        !           677:                break;
        !           678: 
        !           679:        case SRUN:
        !           680:        case SIDL:
        !           681:                *cp = 'R';
        !           682:                break;
        !           683: 
        !           684:        case SZOMB:
        !           685:                *cp = 'Z';
        !           686:                break;
        !           687: 
        !           688:        default:
        !           689:                *cp = '?';
        !           690:        }
        !           691:        cp++;
        !           692:        if (flag & SLOAD) {
        !           693:                if (p->p_rssize > p->p_maxrss)
        !           694:                        *cp++ = '>';
        !           695:        } else
        !           696:                *cp++ = 'W';
        !           697:        if (p->p_nice < NZERO)
        !           698:                *cp++ = '<';
        !           699:        else if (p->p_nice > NZERO)
        !           700:                *cp++ = 'N';
        !           701:        if (flag & SUANOM)
        !           702:                *cp++ = 'A';
        !           703:        else if (flag & SSEQL)
        !           704:                *cp++ = 'S';
        !           705:        if (flag & STRC)
        !           706:                *cp++ = 'X';
        !           707:        if (flag & SWEXIT)
        !           708:                *cp++ = 'E';
        !           709:        if (flag & SVFORK)
        !           710:                *cp++ = 'V';
        !           711:        if (flag & (SSYS|SLOCK|SULOCK|SKEEP|SPHYSIO))
        !           712:                *cp++ = 'L';
        !           713:        if (k->ki_e->e_flag & EPROC_SLEADER)
        !           714:                *cp++ = 's';
        !           715:        if ((flag & SCTTY) && k->ki_e->e_pgid == k->ki_e->e_tpgid)
        !           716:                *cp++ = '+';
        !           717:        *cp = '\0';
        !           718:        printf("%-*s", v->width, buf);
        !           719: }
        !           720: 
        !           721: pri(k, v)
        !           722:        struct kinfo *k;
        !           723:        struct var *v;
        !           724: {
        !           725: 
        !           726:        printf("%*d", v->width, k->ki_p->p_pri - PZERO);
        !           727: }
        !           728: 
        !           729: uname(k, v)
        !           730:        struct kinfo *k;
        !           731:        struct var *v;
        !           732: {
        !           733: 
        !           734:        printf("%-*s", v->width, user_from_uid(k->ki_p->p_uid, 0));
        !           735: }
        !           736: 
        !           737: runame(k, v)
        !           738:        struct kinfo *k;
        !           739:        struct var *v;
        !           740: {
        !           741: 
        !           742:        printf("%-*s", v->width, user_from_uid(k->ki_p->p_ruid, 0));
        !           743: }
        !           744: 
        !           745: tdev(k, v)
        !           746:        struct kinfo *k;
        !           747:        struct var *v;
        !           748: {
        !           749:        dev_t dev = k->ki_e->e_tdev;
        !           750: 
        !           751:        if (dev == NODEV)
        !           752:                printf("%*s", v->width, "??");
        !           753:        else {
        !           754:                char buff[16];
        !           755: 
        !           756:                sprintf(buff, "%d/%d", major(dev), minor(dev));
        !           757:                printf("%*s", v->width, buff);
        !           758:        }
        !           759: }
        !           760: 
        !           761: extern char *devname();
        !           762: 
        !           763: tname(k, v)
        !           764:        struct kinfo *k;
        !           765:        struct var *v;
        !           766: {
        !           767:        dev_t dev = k->ki_e->e_tdev;
        !           768:        char *tname;
        !           769: 
        !           770:        if (dev == NODEV || (tname = devname(dev, S_IFCHR)) == NULL)
        !           771:                printf("%-*s", v->width, "??");
        !           772:        else {
        !           773:                if (strncmp(tname, "tty", 3) == 0)
        !           774:                        tname += 3;
        !           775:                printf("%*.*s%c", v->width-1, v->width-1, tname,
        !           776:                        k->ki_e->e_flag & EPROC_CTTY ? ' ' : '-');
        !           777:        }
        !           778: }
        !           779: 
        !           780: longtname(k, v)
        !           781:        struct kinfo *k;
        !           782:        struct var *v;
        !           783: {
        !           784:        dev_t dev = k->ki_e->e_tdev;
        !           785:        char *tname;
        !           786: 
        !           787:        if (dev == NODEV || (tname = devname(dev, S_IFCHR)) == NULL)
        !           788:                printf("%-*s", v->width, "??");
        !           789:        else
        !           790:                printf("%-*s", v->width, tname);
        !           791: }
        !           792: 
        !           793: #include <sys/time.h>
        !           794: 
        !           795: started(k, v)
        !           796:        struct kinfo *k;
        !           797:        struct var *v;
        !           798: {
        !           799:        extern char *attime();
        !           800: 
        !           801:        printf("%-*s", v->width, k->ki_u ? 
        !           802:                attime(&k->ki_u->u_start.tv_sec) : "-");
        !           803:                
        !           804: }
        !           805: 
        !           806: lstarted(k, v)
        !           807:        struct kinfo *k;
        !           808:        struct var *v;
        !           809: {
        !           810:        extern char *ctime();
        !           811:        char *tp; 
        !           812: 
        !           813:        if (k->ki_u)
        !           814:                (tp = ctime(&k->ki_u->u_start.tv_sec))[24] = '\0';
        !           815:        else
        !           816:                tp = "-";
        !           817:        printf("%-*s", v->width, tp);
        !           818: }
        !           819: 
        !           820: wchan(k, v)
        !           821:        struct kinfo *k;
        !           822:        struct var *v;
        !           823: {
        !           824: 
        !           825:        if (k->ki_p->p_wchan) {
        !           826:                if (k->ki_p->p_pri > PZERO)
        !           827:                        printf("%-*.*s", v->width, v->width, k->ki_e->e_wmesg);
        !           828:                else
        !           829:                        printf("%*x", v->width, 
        !           830:                                (int)k->ki_p->p_wchan &~ KERNBASE);
        !           831:        } else
        !           832:                printf("%-*s", v->width, "-");
        !           833: }
        !           834: 
        !           835: #define pgtok(a)        (((a)*NBPG)/1024)
        !           836: #define pgtok(a)        (((a)*NBPG)/1024)
        !           837: 
        !           838: vsize(k, v)
        !           839:        struct kinfo *k;
        !           840:        struct var *v;
        !           841: {
        !           842: 
        !           843:        printf("%*d", v->width, 
        !           844:                pgtok(k->ki_p->p_dsize + k->ki_p->p_ssize + k->ki_e->e_xsize));
        !           845: }
        !           846: 
        !           847: rssize(k, v)
        !           848:        struct kinfo *k;
        !           849:        struct var *v;
        !           850: {
        !           851: 
        !           852:        printf("%*d", v->width, 
        !           853:                pgtok(k->ki_p->p_rssize + (k->ki_e->e_xccount ? 
        !           854:                      (k->ki_e->e_xrssize / k->ki_e->e_xccount) : 0)));
        !           855: }
        !           856: 
        !           857: p_rssize(k, v)         /* doesn't account for text */
        !           858:        struct kinfo *k;
        !           859:        struct var *v;
        !           860: {
        !           861: 
        !           862:        printf("%*d", v->width, pgtok(k->ki_p->p_rssize));
        !           863: }
        !           864: 
        !           865: cputime(k, v)
        !           866:        struct kinfo *k;
        !           867:        struct var *v;
        !           868: {
        !           869:        long secs;
        !           870:        long psecs;     /* "parts" of a second. first micro, then centi */
        !           871:        char obuff[128];
        !           872: 
        !           873:        if (k->ki_p->p_stat == SZOMB || k->ki_u == NULL) {
        !           874:                secs = 0;
        !           875:                psecs = 0;
        !           876:        } else {
        !           877:                secs = k->ki_p->p_utime.tv_sec + 
        !           878:                        k->ki_p->p_stime.tv_sec;
        !           879:                psecs = k->ki_p->p_utime.tv_usec + 
        !           880:                        k->ki_p->p_stime.tv_usec;
        !           881:                if (sumrusage) {
        !           882:                        secs += k->ki_u->u_cru.ru_utime.tv_sec + 
        !           883:                                k->ki_u->u_cru.ru_stime.tv_sec;
        !           884:                        psecs += k->ki_u->u_cru.ru_utime.tv_usec + 
        !           885:                                k->ki_u->u_cru.ru_stime.tv_usec;
        !           886:                }
        !           887:                /*
        !           888:                 * round and scale to 100's
        !           889:                 */
        !           890:                psecs = (psecs + 5000) / 10000;
        !           891:                if (psecs >= 100) {
        !           892:                        psecs -= 100;
        !           893:                        secs++;
        !           894:                }
        !           895:        }
        !           896:        sprintf(obuff, "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
        !           897:        printf("%*s", v->width, obuff);
        !           898: }
        !           899: 
        !           900: double
        !           901: getpcpu(k)
        !           902:        struct kinfo *k;
        !           903: {
        !           904:        /*
        !           905:         * note: this routine requires ccpu and fscale
        !           906:         * be initialized.  If you call this routine from
        !           907:         * somewhere new, insure that the "neednlist" flag
        !           908:         * gets set.
        !           909:         */
        !           910:        struct proc *p = k->ki_p;
        !           911: #define        fxtofl(fixpt)   ((double)(fixpt) / fscale)
        !           912: 
        !           913:        if (p->p_time == 0 || (p->p_flag & SLOAD) == 0) /* XXX - I don't like this */
        !           914:                return (0.0);
        !           915:        if (rawcpu)
        !           916:                return (100.0 * fxtofl(p->p_pctcpu));
        !           917:        return (100.0 * fxtofl(p->p_pctcpu) /
        !           918:                (1.0 - exp(p->p_time * log(fxtofl(ccpu)))));
        !           919: }
        !           920: 
        !           921: pcpu(k, v)
        !           922:        struct kinfo *k;
        !           923:        struct var *v;
        !           924: {
        !           925: 
        !           926:        printf("%*.1f", v->width, getpcpu(k));
        !           927: }
        !           928: 
        !           929: double
        !           930: getpmem(k, v)
        !           931:        struct kinfo *k;
        !           932:        struct var *v;
        !           933: {
        !           934:        struct proc *p = k->ki_p;
        !           935:        struct eproc *e = k->ki_e;
        !           936:        double fracmem;
        !           937:        int szptudot;
        !           938:        /*
        !           939:         * note: this routine requires that ecmx
        !           940:         * be initialized.  If you call this routine from
        !           941:         * somewhere new, insure that the "neednlist" flag
        !           942:         * gets set.
        !           943:         */
        !           944: 
        !           945:        if (p->p_flag & SLOAD == 0)
        !           946:                return (0.0);
        !           947:        szptudot = UPAGES + clrnd(ctopt(p->p_dsize + p->p_ssize + e->e_xsize));
        !           948:        fracmem = ((float)p->p_rssize + szptudot)/CLSIZE/ecmx;
        !           949:        if (p->p_textp && e->e_xccount)
        !           950:                fracmem += ((float)e->e_xrssize)/CLSIZE/e->e_xccount/ecmx;
        !           951:        return (100.0 * fracmem);
        !           952: }
        !           953: 
        !           954: pmem(k, v)
        !           955:        struct kinfo *k;
        !           956:        struct var *v;
        !           957: {
        !           958: 
        !           959:        printf("%*.1f", v->width, getpmem(k));
        !           960: }
        !           961: 
        !           962: pagein(k, v)
        !           963:        struct kinfo *k;
        !           964:        struct var *v;
        !           965: {
        !           966: 
        !           967:        printf("%*d", v->width, k->ki_u ? k->ki_u->u_ru.ru_majflt : 0);
        !           968: }
        !           969: 
        !           970: maxrss(k, v)
        !           971:        struct kinfo *k;
        !           972:        struct var *v;
        !           973: {
        !           974: 
        !           975:        if (k->ki_p->p_maxrss != (RLIM_INFINITY/NBPG))
        !           976:                printf("%*d", v->width, pgtok(k->ki_p->p_maxrss));
        !           977:        else
        !           978:                printf("%*s", v->width, "-");
        !           979: }
        !           980: 
        !           981: tsize(k, v)
        !           982:        struct kinfo *k;
        !           983:        struct var *v;
        !           984: {
        !           985:        
        !           986:        printf("%*d", v->width, pgtok(k->ki_e->e_xsize));
        !           987: }
        !           988: 
        !           989: trss(k, v)
        !           990:        struct kinfo *k;
        !           991:        struct var *v;
        !           992: {
        !           993: 
        !           994:        printf("%*d", v->width, pgtok(k->ki_e->e_xrssize));
        !           995: }
        !           996: 
        !           997: /*
        !           998:  * Generic output routines.  Print fields from various prototype
        !           999:  * structures.
        !          1000:  */
        !          1001: pvar(k, v) 
        !          1002:        struct kinfo *k;
        !          1003:        struct var *v;
        !          1004: {
        !          1005:  
        !          1006:        printval((char *)((char *)k->ki_p + v->off), v);
        !          1007: }
        !          1008: 
        !          1009: evar(k, v) 
        !          1010:        struct kinfo *k;
        !          1011:        struct var *v;
        !          1012: {
        !          1013:  
        !          1014:        printval((char *)((char *)k->ki_e + v->off), v);
        !          1015: }
        !          1016: 
        !          1017: uvar(k, v) 
        !          1018:        struct kinfo *k;
        !          1019:        struct var *v;
        !          1020: {
        !          1021:  
        !          1022:        if (k->ki_u)
        !          1023:                printval((char *)((char *)k->ki_u + v->off), v);
        !          1024:        else
        !          1025:                printf("%*s", v->width, "-");
        !          1026: }
        !          1027: 
        !          1028: rvar(k, v)
        !          1029:        struct kinfo *k;
        !          1030:        struct var *v;
        !          1031: {
        !          1032:        
        !          1033:        if (k->ki_u)
        !          1034:                printval((char *)((char *)(&k->ki_u->u_ru) + v->off), v);
        !          1035:        else
        !          1036:                printf("%*s", v->width, "-");
        !          1037: }
        !          1038: 
        !          1039: char *
        !          1040: lookupcombo(cp)
        !          1041:        char *cp;
        !          1042: {
        !          1043:        register struct combovar *cv = &combovar[0];
        !          1044: 
        !          1045:        for (; cv->name; cv++)
        !          1046:                if (strcmp(cp, cv->name) == 0)
        !          1047:                        return (cv->replace);
        !          1048:        return (NULL);
        !          1049: }
        !          1050: 
        !          1051: struct var *
        !          1052: lookupvar(cp)
        !          1053:        char *cp;
        !          1054: {
        !          1055:        register int i, j;
        !          1056: 
        !          1057:        for (i=0; var[i].name[0] != NULL; i++)
        !          1058:                for (j=0; var[i].name[j] != NULL; j++)
        !          1059:                        if (strcmp(cp, var[i].name[j]) == 0)
        !          1060:                                return (&var[i]);
        !          1061:        return (NULL);
        !          1062: }
        !          1063: 
        !          1064: printval(bp, v)
        !          1065:        char *bp;
        !          1066:        struct var *v;
        !          1067: {
        !          1068:        static char ofmt[32] = "%";
        !          1069:        register char *cp = ofmt+1, *fcp = v->fmt;
        !          1070: 
        !          1071:        if (v->flag & LJUST)
        !          1072:                *cp++ = '-';
        !          1073:        *cp++ = '*';
        !          1074:        while (*cp++ = *fcp++)
        !          1075:                ;
        !          1076: 
        !          1077:        switch (v->type) {
        !          1078:        case CHAR:
        !          1079:                printf(ofmt, v->width, *(char *)bp);
        !          1080:                break;
        !          1081: 
        !          1082:        case UCHAR:
        !          1083:                printf(ofmt, v->width, *(u_char *)bp);
        !          1084:                break;
        !          1085: 
        !          1086:        case SHORT:
        !          1087:                printf(ofmt, v->width, *(short *)bp);
        !          1088:                break;
        !          1089: 
        !          1090:        case USHORT:
        !          1091:                printf(ofmt, v->width, *(u_short *)bp);
        !          1092:                break;
        !          1093: 
        !          1094:        case LONG:
        !          1095:                printf(ofmt, v->width, *(long *)bp);
        !          1096:                break;
        !          1097: 
        !          1098:        case ULONG:
        !          1099:                printf(ofmt, v->width, *(u_long *)bp);
        !          1100:                break;
        !          1101: 
        !          1102:        case KPTR:
        !          1103:                printf(ofmt, v->width, *(u_long *)bp &~ KERNBASE);
        !          1104:                break;
        !          1105: 
        !          1106:        default:
        !          1107:                error("unknown type %d", v->type);
        !          1108:        }
        !          1109: }
        !          1110: 
        !          1111: /* XXX - redo */
        !          1112: struct usave *
        !          1113: saveuser(ki) 
        !          1114:        struct kinfo *ki;
        !          1115: {
        !          1116:        register struct usave *usp;
        !          1117:        register struct user *up;
        !          1118:        
        !          1119:        if ((usp = (struct usave *)calloc(1, sizeof (struct usave))) == NULL) {
        !          1120:                fprintf(stderr, "ps: out of memory\n");
        !          1121:                exit(1);
        !          1122:        }
        !          1123:        ki->ki_u = usp;
        !          1124:        up = kvm_getu(ki->ki_p);
        !          1125:        /*
        !          1126:         * save arguments if needed
        !          1127:         */
        !          1128:        if (needcomm)
        !          1129:                ki->ki_args = saveargs(ki->ki_p, up);
        !          1130:        else
        !          1131:                ki->ki_args = NULL;
        !          1132:        if (up != NULL) { 
        !          1133:                /*
        !          1134:                 * save important fields
        !          1135:                 */
        !          1136:                usp->u_procp = up->u_procp;
        !          1137:                usp->u_start = up->u_start;
        !          1138:                usp->u_ru = up->u_ru;
        !          1139:                usp->u_cru = up->u_cru;
        !          1140:                usp->u_cmask = up->u_cmask;
        !          1141:                usp->u_acflag = up->u_acflag;
        !          1142:        }
        !          1143:        return;
        !          1144: }
        !          1145: 
        !          1146: char *
        !          1147: saveargs(p, up)
        !          1148:        struct proc *p;
        !          1149:        struct user *up;
        !          1150: {
        !          1151:        char *savestr();
        !          1152: 
        !          1153:        return(savestr(kvm_getargs(p, up)));
        !          1154: }
        !          1155:        
        !          1156: 
        !          1157: pscomp(k1, k2)
        !          1158:        struct kinfo *k1, *k2;
        !          1159: {
        !          1160:        int i;
        !          1161: #define VSIZE(k) ((k)->ki_p->p_dsize + (k)->ki_p->p_ssize + (k)->ki_e->e_xsize)
        !          1162: 
        !          1163:        if (sortby == SORTCPU)
        !          1164:                return (getpcpu(k2) - getpcpu(k1));
        !          1165: #ifdef notyet
        !          1166:        if (sortby == SORTRUN)
        !          1167:                return (proc_compare(k1->ki_p, k2->ki_p));
        !          1168: #endif
        !          1169:        if (sortby == SORTMEM)
        !          1170:                return (VSIZE(k2) - VSIZE(k1));
        !          1171:        i =  k1->ki_e->e_tdev - k2->ki_e->e_tdev;
        !          1172:        if (i == 0)
        !          1173:                i = k1->ki_p->p_pid - k2->ki_p->p_pid;
        !          1174:        return (i);
        !          1175: }
        !          1176: 
        !          1177: donlist()
        !          1178: {
        !          1179:        if (kvm_nlist(psnl) != 0)
        !          1180:                error("can't get namelist");
        !          1181:        if (kvm_read(psnl[X_FSCALE].n_value, &fscale, sizeof(int)) !=
        !          1182:            sizeof (int))
        !          1183:                error("error reading fscale: %s", kvm_geterr());
        !          1184:        if (kvm_read(psnl[X_ECMX].n_value, &ecmx, sizeof(int)) !=
        !          1185:            sizeof (int))
        !          1186:                error("error reading ecmx: %s", kvm_geterr());
        !          1187:        if (kvm_read(psnl[X_CCPU].n_value, &ccpu, sizeof(fixpt_t)) !=
        !          1188:            sizeof (fixpt_t))
        !          1189:                error("error reading ccpu: %s", kvm_geterr());
        !          1190: }
        !          1191: 
        !          1192: char *
        !          1193: savestr(cp)
        !          1194:        char *cp;
        !          1195: {
        !          1196:        register unsigned len;
        !          1197:        register char *dp;
        !          1198: 
        !          1199:        len = strlen(cp);
        !          1200:        dp = (char *)calloc(len+1, sizeof (char));
        !          1201:        (void) strcpy(dp, cp);
        !          1202:        return (dp);
        !          1203: }
        !          1204: 
        !          1205: error(a, b, c, d, e)
        !          1206:        char *a, *b, *c, *d, *e;
        !          1207: {
        !          1208:        fprintf(stderr, "ps: ");
        !          1209:        fprintf(stderr, a, b, c, d, e);
        !          1210:        fprintf(stderr, "\n");
        !          1211:        exit(1);
        !          1212: }
        !          1213: 
        !          1214: syserror(a)
        !          1215:        char *a;
        !          1216: {
        !          1217:        extern errno;
        !          1218: 
        !          1219:        error("%s: %s", a, strerror(errno));
        !          1220: }
        !          1221: 
        !          1222: /*
        !          1223:  * ICK (all for getopt), would rather hide the ugliness
        !          1224:  * here than taint the main code.
        !          1225:  *
        !          1226:  *  ps foo -> ps -foo
        !          1227:  *  ps 34 -> ps -p34
        !          1228:  *
        !          1229:  * The old convention that 't' with no trailing tty arg means the users
        !          1230:  * tty, is only supported if argv[1] doesn't begin with a '-'.  This same
        !          1231:  * feature is available with the option 'T', which takes no argument.
        !          1232:  */
        !          1233: char *
        !          1234: kludge_oldps_options(s)
        !          1235:        char *s;
        !          1236: {
        !          1237:        int len = strlen(s), numlen = 0;
        !          1238:        char *newopts, *ns, *cp;
        !          1239: 
        !          1240:        if ((newopts = ns = (char *)malloc(len+2)) == NULL)
        !          1241:                error("out of memory");
        !          1242:        /*
        !          1243:         * options begin with '-'
        !          1244:         */
        !          1245:        if (*s != '-')
        !          1246:                *ns++ = '-';    /* add option flag */
        !          1247:        /*
        !          1248:         * gaze to end of argv[1]
        !          1249:         */
        !          1250:        cp = s + len - 1;
        !          1251:        /*
        !          1252:         * if last letter is a 't' flag with no argument (in the context
        !          1253:         * of the oldps options -- option string NOT starting with a '-' --
        !          1254:         * then convert to 'T' (meaning *this* terminal, i.e. ttyname(0).
        !          1255:         */
        !          1256:        if (*cp == 't' && *s != '-')
        !          1257:                *cp = 'T';
        !          1258:        else {
        !          1259:                /*
        !          1260:                 * otherwise check for trailing number, which *may* be a
        !          1261:                 * pid.
        !          1262:                 */
        !          1263:                while (isdigit(*cp)) {
        !          1264:                        --cp;
        !          1265:                        numlen++;
        !          1266:                }
        !          1267:        }
        !          1268:        cp++;
        !          1269:        bcopy(s, ns, cp - s);   /* copy everything up to trailing number */
        !          1270:        while (*ns)
        !          1271:                ns++;
        !          1272:        /*
        !          1273:         * if there's a trailing number, and not a preceding 'p' (pid) or
        !          1274:         * 't' (tty) flag, then assume it's a pid and insert a 'p' flag.
        !          1275:         */
        !          1276:        if (isdigit(*cp) && (cp == s || *(cp-1) != 't' && *(cp-1) != 'p' &&
        !          1277:           ((cp-1) == s || *(cp-2) != 't')))
        !          1278:                *ns++ = 'p';
        !          1279:        strcat(ns, cp);         /* and append the number */
        !          1280: 
        !          1281:        return (newopts);
        !          1282: }

unix.superglobalmegacorp.com

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