update to new fs
[unix-history] / usr / src / bin / ps / ps.c
index 69b1f8a..11414d9 100644 (file)
@@ -1,6 +1,9 @@
-static char *sccsid = "@(#)ps.c        4.3 (Berkeley) %G%";
+#ifndef lint
+static char *sccsid = "@(#)ps.c        4.17 (Berkeley) %G%";
+#endif
+
 /*
 /*
- * ps; VAX 4BSD version
+ * ps
  */
 
 #include <stdio.h>
  */
 
 #include <stdio.h>
@@ -9,7 +12,7 @@ static char *sccsid = "@(#)ps.c        4.3 (Berkeley) %G%";
 #include <pwd.h>
 #include <sys/param.h>
 #include <sys/tty.h>
 #include <pwd.h>
 #include <sys/param.h>
 #include <sys/tty.h>
-#include <sys/dir.h>
+#include <dir.h>
 #include <sys/user.h>
 #include <sys/proc.h>
 #include <sys/pte.h>
 #include <sys/user.h>
 #include <sys/proc.h>
 #include <sys/pte.h>
@@ -17,6 +20,7 @@ static        char *sccsid = "@(#)ps.c        4.3 (Berkeley) %G%";
 #include <sys/text.h>
 #include <sys/stat.h>
 #include <math.h>
 #include <sys/text.h>
 #include <sys/stat.h>
 #include <math.h>
+#include <sys/vlimit.h>
 
 struct nlist nl[] = {
        { "_proc" },
 
 struct nlist nl[] = {
        { "_proc" },
@@ -33,6 +37,14 @@ struct nlist nl[] = {
 #define        X_MAXSLP        5
        { "_ccpu" },
 #define        X_CCPU          6
 #define        X_MAXSLP        5
        { "_ccpu" },
 #define        X_CCPU          6
+       { "_ecmx" },
+#define        X_ECMX          7
+       { "_nproc" },
+#define        X_NPROC         8
+       { "_ntext" },
+#define        X_NTEXT         9
+       { "_hz" },
+#define        X_HZ            10
        { 0 },
 };
 
        { 0 },
 };
 
@@ -42,22 +54,24 @@ struct      savcom {
                float   u_pctcpu;
                struct  vsav *vp;
                int     s_ssiz;
                float   u_pctcpu;
                struct  vsav *vp;
                int     s_ssiz;
+               struct  sssav *ssp;
        } sun;
        struct  asav *ap;
        } sun;
        struct  asav *ap;
-} savcom[NPROC];
+} *savcom;
 
 struct asav {
        char    *a_cmdp;
        int     a_flag;
        short   a_stat, a_uid, a_pid, a_nice, a_pri, a_slptime, a_time;
 
 struct asav {
        char    *a_cmdp;
        int     a_flag;
        short   a_stat, a_uid, a_pid, a_nice, a_pri, a_slptime, a_time;
-       size_t  a_size, a_rss;
-       char    a_tty[DIRSIZ+1];
+       size_t  a_size, a_rss, a_tsiz, a_txtrss;
+       short   a_xccount;
+       char    a_tty[MAXNAMLEN+1];
        dev_t   a_ttyd;
        time_t  a_cpu;
        dev_t   a_ttyd;
        time_t  a_cpu;
+       size_t  a_maxrss;
 };
 
 char   *lhdr;
 };
 
 char   *lhdr;
-/*          F UID   PID  PPID CP PRI NI ADDR  SZ  RSS WCHAN ST TT  TIME */
 struct lsav {
        short   l_ppid;
        char    l_cpu;
 struct lsav {
        short   l_ppid;
        char    l_cpu;
@@ -65,19 +79,21 @@ struct      lsav {
        caddr_t l_wchan;
 };
 
        caddr_t l_wchan;
 };
 
-char   *uhdr;
-/*     USER       PID %CPU NI   SZ  RSS TT ST TIME */
+char   *sshdr;
+struct sssav {
+       short   ss_ppid;
+       short   ss_brother;
+       short   ss_sons;
+};
 
 
+char   *uhdr;
 char   *shdr;
 char   *shdr;
-/*     SSIZ   PID TT ST TIME */
 
 char   *vhdr;
 
 char   *vhdr;
-/*        PID TT ST    TIME RES SL MINFLT MAJFLT SIZE  RSS  SRS TSIZ TRS %CP*/
 struct vsav {
 struct vsav {
-       u_int   v_minflt, v_majflt;
-       size_t  v_swrss, v_tsiz, v_txtrss, v_txtswrss;
-       short   v_xccount;
-       short   v_pctcpu;
+       u_int   v_majflt;
+       size_t  v_swrss, v_txtswrss;
+       float   v_pctcpu;
 };
 
 struct proc proc[8];           /* 8 = a few, for less syscalls */
 };
 
 struct proc proc[8];           /* 8 = a few, for less syscalls */
@@ -93,29 +109,35 @@ union {
 #define clear(x)       ((int)x & 0x7fffffff)
 
 int    chkpid;
 #define clear(x)       ((int)x & 0x7fffffff)
 
 int    chkpid;
-int    aflg, cflg, eflg, gflg, kflg, lflg, sflg, uflg, vflg, xflg;
+int    aflg, cflg, eflg, gflg, kflg, lflg, sflg, ssflg,
+       nonssflg, uflg, vflg, xflg;
 char   *tptr;
 char   *gettty(), *getcmd(), *getname(), *savestr(), *alloc(), *state();
 char   *tptr;
 char   *gettty(), *getcmd(), *getname(), *savestr(), *alloc(), *state();
-double pcpu();
+char   *rindex(), *calloc(), *sbrk(), *strcpy(), *strcat(), *strncat();
+long   lseek();
+double pcpu(), pmem();
 int    pscomp();
 int    nswap, maxslp;
 int    pscomp();
 int    nswap, maxslp;
+struct text *atext;
 double ccpu;
 double ccpu;
+int    ecmx;
 struct pte *Usrptma, *usrpt;
 struct pte *Usrptma, *usrpt;
+int    nproc, ntext, hz;
 
 struct ttys {
 
 struct ttys {
-       char    name[DIRSIZ+1];
+       char    name[MAXNAMLEN+1];
        dev_t   ttyd;
        struct  ttys *next;
        struct  ttys *cand;
 } *allttys, *cand[16];
 
        dev_t   ttyd;
        struct  ttys *next;
        struct  ttys *cand;
 } *allttys, *cand[16];
 
-struct savcom savcom[NPROC];
 int    npr;
 
 int    cmdstart;
 int    twidth;
 char   *kmemf, *memf, *swapf, *nlistf;
 int    kmem, mem, swap;
 int    npr;
 
 int    cmdstart;
 int    twidth;
 char   *kmemf, *memf, *swapf, *nlistf;
 int    kmem, mem, swap;
+int    rawcpu, sumcpu;
 
 int    pcbpf;
 int    argaddr;
 
 int    pcbpf;
 int    argaddr;
@@ -134,49 +156,62 @@ main(argc, argv)
                exit(1);
        }
        twidth = 80;
                exit(1);
        }
        twidth = 80;
-       setbuf(stdout, _sobuf);
+
+       if (ap = rindex(argv[0], '/'))
+               ap++;
+       else
+               ap = argv[0];
+       if (*ap == 's')                         /* If name starts with 's' */
+               ssflg++;
+
        argc--, argv++;
        if (argc > 0) {
                ap = argv[0];
                while (*ap) switch (*ap++) {
 
        argc--, argv++;
        if (argc > 0) {
                ap = argv[0];
                while (*ap) switch (*ap++) {
 
+               case 'C':
+                       rawcpu++; nonssflg++;
+                       break;
+               case 'S':
+                       sumcpu++;
+                       break;
                case 'a':
                        aflg++;
                        break;
                case 'c':
                case 'a':
                        aflg++;
                        break;
                case 'c':
-                       cflg = !cflg;
+                       cflg = !cflg; nonssflg++;
                        break;
                case 'e':
                        break;
                case 'e':
-                       eflg++;
+                       eflg++; nonssflg++;
                        break;
                case 'g':
                        break;
                case 'g':
-                       gflg++;
+                       gflg++; nonssflg++;
                        break;
                case 'k':
                        break;
                case 'k':
-                       kflg++;
+                       kflg++; nonssflg++;
                        break;
                case 'l':
                        break;
                case 'l':
-                       lflg++;
+                       lflg++; nonssflg++;
                        break;
                case 's':
                        break;
                case 's':
-                       sflg++;
+                       sflg++; nonssflg++;
                        break;
                case 't':
                        if (*ap)
                                tptr = ap;
                        break;
                case 't':
                        if (*ap)
                                tptr = ap;
-                       aflg++;
+                       aflg++; nonssflg++;
                        gflg++;
                        if (*tptr == '?')
                                xflg++;
                        while (*ap)
                                ap++;
                        break;
                        gflg++;
                        if (*tptr == '?')
                                xflg++;
                        while (*ap)
                                ap++;
                        break;
-               case 'u':
-                       uflg++;
+               case 'u': 
+                       uflg++; nonssflg++;
                        break;
                case 'v':
                        cflg = 1;
                        break;
                case 'v':
                        cflg = 1;
-                       vflg++;
+                       vflg++; nonssflg++;
                        break;
                case 'w':
                        if (twidth == 80)
                        break;
                case 'w':
                        if (twidth == 80)
@@ -187,25 +222,40 @@ main(argc, argv)
                case 'x':
                        xflg++;
                        break;
                case 'x':
                        xflg++;
                        break;
+               case 'y':               /* Rand 2/81 */
+                       ssflg++;
+                       break;
                default:
                        if (!isdigit(ap[-1]))
                                break;
                        chkpid = atoi(--ap);
                        *ap = 0;
                default:
                        if (!isdigit(ap[-1]))
                                break;
                        chkpid = atoi(--ap);
                        *ap = 0;
-                       aflg++;
+                       aflg++; nonssflg++;
                        xflg++;
                        break;
                }
        }
                        xflg++;
                        break;
                }
        }
+       if (ssflg) {
+               if (nonssflg) {
+                       fprintf (stderr, "Usage: ss [axwS]\n");
+                       exit(1);
+               }
+               uflg++;
+               gflg++;
+       }
+
        openfiles(argc, argv);
        getkvars(argc, argv);
        getdev();
        uid = getuid();
        printhdr();
        openfiles(argc, argv);
        getkvars(argc, argv);
        getdev();
        uid = getuid();
        printhdr();
-       procp = nl[X_PROC].n_value;
-       for (i=0; i<NPROC; i += 8) {
-               lseek(kmem, (char *)procp, 0);
-               j = NPROC - i;
+       procp = getw(nl[X_PROC].n_value);
+       nproc = getw(nl[X_NPROC].n_value);
+       hz = getw(nl[X_HZ].n_value);
+       savcom = (struct savcom *)calloc(nproc, sizeof (*savcom));
+       for (i=0; i<nproc; i += 8) {
+               klseek(kmem, (long)procp, 0);
+               j = nproc - i;
                if (j > 8)
                        j = 8;
                j *= sizeof (struct proc);
                if (j > 8)
                        j = 8;
                j *= sizeof (struct proc);
@@ -218,7 +268,7 @@ main(argc, argv)
                            mproc->p_pgrp == 0 && xflg == 0)
                                continue;
                        if (tptr == 0 && gflg == 0 && xflg == 0 &&
                            mproc->p_pgrp == 0 && xflg == 0)
                                continue;
                        if (tptr == 0 && gflg == 0 && xflg == 0 &&
-                           mproc->p_ppid == 1 && (mproc->p_flag&SDETACH) == 0)
+                           mproc->p_ppid == 1)
                                continue;
                        if (uid != mproc->p_uid && aflg==0 ||
                            chkpid != 0 && chkpid != mproc->p_pid)
                                continue;
                        if (uid != mproc->p_uid && aflg==0 ||
                            chkpid != 0 && chkpid != mproc->p_pid)
@@ -236,6 +286,10 @@ main(argc, argv)
                }
        }
        qsort(savcom, npr, sizeof(savcom[0]), pscomp);
                }
        }
        qsort(savcom, npr, sizeof(savcom[0]), pscomp);
+       if (ssflg) {
+               walk(npr);
+               exit (npr == 0);
+       }
        for (i=0; i<npr; i++) {
                register struct savcom *sp = &savcom[i];
                if (lflg)
        for (i=0; i<npr; i++) {
                register struct savcom *sp = &savcom[i];
                if (lflg)
@@ -254,6 +308,8 @@ main(argc, argv)
                        printf(" swapper");
                else if (sp->ap->a_pid == 2)
                        printf(" pagedaemon");
                        printf(" swapper");
                else if (sp->ap->a_pid == 2)
                        printf(" pagedaemon");
+               else if (sp->ap->a_pid == 3 && sp->ap->a_flag & SSYS)
+                       printf(" ip input");
                else
                        printf(" %.*s", twidth - cmdstart - 2, sp->ap->a_cmdp);
                printf("\n");
                else
                        printf(" %.*s", twidth - cmdstart - 2, sp->ap->a_cmdp);
                printf("\n");
@@ -261,6 +317,28 @@ main(argc, argv)
        exit(npr == 0);
 }
 
        exit(npr == 0);
 }
 
+getw(loc)
+       unsigned long loc;
+{
+       long word;
+
+       klseek(kmem, (long)loc, 0);
+       if (read(kmem, (char *)&word, sizeof (word)) != sizeof (word))
+               printf("error reading kmem at %x\n", loc);
+       return (word);
+}
+
+klseek(fd, loc, off)
+       int fd;
+       long loc;
+       int off;
+{
+
+       if (kflg)
+               loc &= 0x7fffffff;
+       (void) lseek(fd, (long)loc, off);
+}
+
 openfiles(argc, argv)
        char **argv;
 {
 openfiles(argc, argv)
        char **argv;
 {
@@ -308,30 +386,37 @@ getkvars(argc, argv)
                        nlp->n_value = clear(nlp->n_value);
        Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
        usrpt = (struct pte *)nl[X_USRPT].n_value;
                        nlp->n_value = clear(nlp->n_value);
        Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
        usrpt = (struct pte *)nl[X_USRPT].n_value;
-       lseek(kmem, (long)nl[X_NSWAP].n_value, 0);
-       if (read(kmem, &nswap, sizeof (nswap)) != sizeof (nswap)) {
+       klseek(kmem, (long)nl[X_NSWAP].n_value, 0);
+       if (read(kmem, (char *)&nswap, sizeof (nswap)) != sizeof (nswap)) {
                cantread("nswap", kmemf);
                exit(1);
        }
                cantread("nswap", kmemf);
                exit(1);
        }
-       lseek(kmem, (long)nl[X_MAXSLP].n_value, 0);
-       if (read(kmem, &maxslp, sizeof (maxslp)) != sizeof (maxslp)) {
+       klseek(kmem, (long)nl[X_MAXSLP].n_value, 0);
+       if (read(kmem, (char *)&maxslp, sizeof (maxslp)) != sizeof (maxslp)) {
                cantread("maxslp", kmemf);
                exit(1);
        }
                cantread("maxslp", kmemf);
                exit(1);
        }
-       lseek(kmem, (long)nl[X_CCPU].n_value, 0);
-       if (read(kmem, &ccpu, sizeof (ccpu)) != sizeof (ccpu)) {
+       klseek(kmem, (long)nl[X_CCPU].n_value, 0);
+       if (read(kmem, (char *)&ccpu, sizeof (ccpu)) != sizeof (ccpu)) {
                cantread("ccpu", kmemf);
                exit(1);
        }
                cantread("ccpu", kmemf);
                exit(1);
        }
-       if (vflg) {
-               text = (struct text *)alloc(NTEXT * sizeof (struct text));
+       klseek(kmem, (long)nl[X_ECMX].n_value, 0);
+       if (read(kmem, (char *)&ecmx, sizeof (ecmx)) != sizeof (ecmx)) {
+               cantread("ecmx", kmemf);
+               exit(1);
+       }
+       if (uflg || vflg) {
+               ntext = getw(nl[X_NTEXT].n_value);
+               text = (struct text *)alloc(ntext * sizeof (struct text));
                if (text == 0) {
                        fprintf(stderr, "no room for text table\n");
                        exit(1);
                }
                if (text == 0) {
                        fprintf(stderr, "no room for text table\n");
                        exit(1);
                }
-               lseek(kmem, (long)nl[X_TEXT].n_value, 0);
-               if (read(kmem, (char *)text, NTEXT * sizeof (struct text))
-                   != NTEXT * sizeof (struct text)) {
+               atext = (struct text *)getw(nl[X_TEXT].n_value);
+               klseek(kmem, (long)atext, 0);
+               if (read(kmem, (char *)text, ntext * sizeof (struct text))
+                   != ntext * sizeof (struct text)) {
                        cantread("text table", kmemf);
                        exit(1);
                }
                        cantread("text table", kmemf);
                        exit(1);
                }
@@ -346,12 +431,15 @@ printhdr()
                fprintf(stderr, "ps: specify only one of s,l,v and u\n");
                exit(1);
        }
                fprintf(stderr, "ps: specify only one of s,l,v and u\n");
                exit(1);
        }
-       hdr = lflg ? lhdr : (vflg ? vhdr : (uflg ? uhdr : shdr));
+       hdr = ssflg ? sshdr :
+               (lflg ? lhdr : 
+                       (vflg ? vhdr : 
+                               (uflg ? uhdr : shdr))); 
        if (lflg+vflg+uflg+sflg == 0)
                hdr += strlen("SSIZ ");
        cmdstart = strlen(hdr);
        printf("%s COMMAND\n", hdr);
        if (lflg+vflg+uflg+sflg == 0)
                hdr += strlen("SSIZ ");
        cmdstart = strlen(hdr);
        printf("%s COMMAND\n", hdr);
-       fflush(stdout);
+       (void) fflush(stdout);
 }
 
 cantread(what, fromwhat)
 }
 
 cantread(what, fromwhat)
@@ -361,25 +449,21 @@ cantread(what, fromwhat)
        fprintf(stderr, "ps: error reading %s from %s", what, fromwhat);
 }
 
        fprintf(stderr, "ps: error reading %s from %s", what, fromwhat);
 }
 
-struct direct dbuf;
+struct direct *dbuf;
 int    dialbase;
 
 getdev()
 {
 int    dialbase;
 
 getdev()
 {
-       register FILE *df;
-       register struct ttys *dp;
+       register DIR *df;
 
        dialbase = -1;
 
        dialbase = -1;
-       if ((df = fopen(".", "r")) == NULL) {
+       if ((df = opendir(".")) == NULL) {
                fprintf(stderr, "Can't open . in /dev\n");
                exit(1);
        }
                fprintf(stderr, "Can't open . in /dev\n");
                exit(1);
        }
-       while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) {
-               if (dbuf.d_ino == 0)
-                       continue;
-               maybetty(dp);
-       }
-       fclose(df);
+       while ((dbuf = readdir(df)) != NULL) 
+               maybetty();
+       closedir(df);
 }
 
 /*
 }
 
 /*
@@ -390,7 +474,7 @@ getdev()
  */
 maybetty()
 {
  */
 maybetty()
 {
-       register char *cp = dbuf.d_name;
+       register char *cp = dbuf->d_name;
        register struct ttys *dp;
        int x;
        struct stat stb;
        register struct ttys *dp;
        int x;
        struct stat stb;
@@ -407,12 +491,12 @@ maybetty()
 
        case 'd':
                if (!strcmp(cp, "drum"))
 
        case 'd':
                if (!strcmp(cp, "drum"))
-                       return (0);
+                       return;
                break;
 
        case 'f':
                if (!strcmp(cp, "floppy"))
                break;
 
        case 'f':
                if (!strcmp(cp, "floppy"))
-                       return (0);
+                       return;
                break;
 
        case 'k':
                break;
 
        case 'k':
@@ -429,32 +513,30 @@ maybetty()
                if (is(r,p) || is(u,p) || is(r,k) || is(r,m) || is(m,t)) {
                        cp += 2;
                        if (isdigit(*cp) && cp[2] == 0)
                if (is(r,p) || is(u,p) || is(r,k) || is(r,m) || is(m,t)) {
                        cp += 2;
                        if (isdigit(*cp) && cp[2] == 0)
-                               return (0);
+                               return;
                }
                break;
 
        case 'm':
 trymem:
                if (cp[0] == 'm' && cp[1] == 'e' && cp[2] == 'm' && cp[3] == 0)
                }
                break;
 
        case 'm':
 trymem:
                if (cp[0] == 'm' && cp[1] == 'e' && cp[2] == 'm' && cp[3] == 0)
-                       return (0);
+                       return;
+               if (cp[0] == 'm' && cp[1] == 't')
+                       return;
                break;
 
        case 'n':
                if (!strcmp(cp, "null"))
                break;
 
        case 'n':
                if (!strcmp(cp, "null"))
-                       return (0);
+                       return;
                break;
 
        case 'v':
                if ((cp[1] == 'a' || cp[1] == 'p') && isdigit(cp[2]) &&
                    cp[3] == 0)
                break;
 
        case 'v':
                if ((cp[1] == 'a' || cp[1] == 'p') && isdigit(cp[2]) &&
                    cp[3] == 0)
-                       return (0);
+                       return;
                break;
        }
                break;
        }
-mightbe:
-       cp = dbuf.d_name;
-       while (cp < &dbuf.d_name[DIRSIZ] && *cp)
-               cp++;
-       --cp;
+       cp = dbuf->d_name + dbuf->d_namlen - 1;
        x = 0;
        if (cp[-1] == 'd') {
                if (dialbase == -1) {
        x = 0;
        if (cp[-1] == 'd') {
                if (dialbase == -1) {
@@ -468,7 +550,7 @@ mightbe:
                else
                        x = 11;
        }
                else
                        x = 11;
        }
-       if (cp > dbuf.d_name && isdigit(cp[-1]) && isdigit(*cp))
+       if (cp > dbuf->d_name && isdigit(cp[-1]) && isdigit(*cp))
                x += 10 * (cp[-1] - ' ') + cp[0] - '0';
        else if (*cp >= 'a' && *cp <= 'f')
                x += 10 + *cp - 'a';
                x += 10 * (cp[-1] - ' ') + cp[0] - '0';
        else if (*cp >= 'a' && *cp <= 'f')
                x += 10 + *cp - 'a';
@@ -478,7 +560,7 @@ mightbe:
                x = -1;
 donecand:
        dp = (struct ttys *)alloc(sizeof (struct ttys));
                x = -1;
 donecand:
        dp = (struct ttys *)alloc(sizeof (struct ttys));
-       strncpy(dp->name, dbuf.d_name, DIRSIZ);
+       (void) strcpy(dp->name, dbuf->d_name);
        dp->next = allttys;
        dp->ttyd = -1;
        allttys = dp;
        dp->next = allttys;
        dp->ttyd = -1;
        allttys = dp;
@@ -514,7 +596,8 @@ gettty()
        /* ick */
        for (dp = allttys; dp; dp = dp->next) {
                if (dp->ttyd == -1) {
        /* ick */
        for (dp = allttys; dp; dp = dp->next) {
                if (dp->ttyd == -1) {
-                       if (stat(dp->name, &stb) == 0)
+                       if (stat(dp->name, &stb) == 0 &&
+                          (stb.st_mode&S_IFMT)==S_IFCHR)
                                dp->ttyd = stb.st_rdev;
                        else
                                dp->ttyd = -2;
                                dp->ttyd = stb.st_rdev;
                        else
                                dp->ttyd = -2;
@@ -535,12 +618,13 @@ save()
        register struct savcom *sp;
        register struct asav *ap;
        register char *cp;
        register struct savcom *sp;
        register struct asav *ap;
        register char *cp;
+       register struct text *xp;
        char *ttyp, *cmdp;
 
        if (mproc->p_stat != SZOMB && getu() == 0)
                return;
        ttyp = gettty();
        char *ttyp, *cmdp;
 
        if (mproc->p_stat != SZOMB && getu() == 0)
                return;
        ttyp = gettty();
-       if (xflg == 0 && ttyp[0] == '?' || tptr && strcmpn(tptr, ttyp, 2))
+       if (xflg == 0 && ttyp[0] == '?' || tptr && strncmp(tptr, ttyp, 2))
                return;
        sp = &savcom[npr];
        cmdp = getcmd();
                return;
        sp = &savcom[npr];
        cmdp = getcmd();
@@ -550,9 +634,8 @@ save()
        sp->ap->a_cmdp = cmdp;
 #define e(a,b) ap->a = mproc->b
        e(a_flag, p_flag); e(a_stat, p_stat); e(a_nice, p_nice);
        sp->ap->a_cmdp = cmdp;
 #define e(a,b) ap->a = mproc->b
        e(a_flag, p_flag); e(a_stat, p_stat); e(a_nice, p_nice);
-       e(a_uid, p_uid); e(a_pid, p_pid); e(a_rss, p_rssize); e(a_pri, p_pri);
+       e(a_uid, p_uid); e(a_pid, p_pid); e(a_pri, p_pri);
        e(a_slptime, p_slptime); e(a_time, p_time);
        e(a_slptime, p_slptime); e(a_time, p_time);
-#undef e
        ap->a_tty[0] = ttyp[0];
        ap->a_tty[1] = ttyp[1] ? ttyp[1] : ' ';
        if (ap->a_stat == SZOMB) {
        ap->a_tty[0] = ttyp[0];
        ap->a_tty[1] = ttyp[1] ? ttyp[1] : ' ';
        if (ap->a_stat == SZOMB) {
@@ -561,10 +644,21 @@ save()
                ap->a_cpu = xp->xp_vm.vm_utime + xp->xp_vm.vm_stime;
        } else {
                ap->a_size = mproc->p_dsize + mproc->p_ssize;
                ap->a_cpu = xp->xp_vm.vm_utime + xp->xp_vm.vm_stime;
        } else {
                ap->a_size = mproc->p_dsize + mproc->p_ssize;
+               e(a_rss, p_rssize); 
                ap->a_ttyd = u.u_ttyd;
                ap->a_cpu = u.u_vm.vm_utime + u.u_vm.vm_stime;
                ap->a_ttyd = u.u_ttyd;
                ap->a_cpu = u.u_vm.vm_utime + u.u_vm.vm_stime;
+               if (sumcpu)
+                       ap->a_cpu += u.u_cvm.vm_utime + u.u_cvm.vm_stime;
+               if (mproc->p_textp && text) {
+                       xp = &text[mproc->p_textp - atext];
+                       ap->a_tsiz = xp->x_size;
+                       ap->a_txtrss = xp->x_rssize;
+                       ap->a_xccount = xp->x_ccount;
+               }
        }
        }
-       ap->a_cpu /= HZ;
+#undef e
+       ap->a_cpu /= hz;
+       ap->a_maxrss = mproc->p_maxrss;
        if (lflg) {
                register struct lsav *lp;
 
        if (lflg) {
                register struct lsav *lp;
 
@@ -577,57 +671,81 @@ save()
                lp->l_addr = pcbpf;
        } else if (vflg) {
                register struct vsav *vp;
                lp->l_addr = pcbpf;
        } else if (vflg) {
                register struct vsav *vp;
-               register struct text *xp;
 
                sp->sun.vp = vp = (struct vsav *)alloc(sizeof (struct vsav));
 #define e(a,b) vp->a = mproc->b
                if (ap->a_stat != SZOMB) {
                        e(v_swrss, p_swrss);
 
                sp->sun.vp = vp = (struct vsav *)alloc(sizeof (struct vsav));
 #define e(a,b) vp->a = mproc->b
                if (ap->a_stat != SZOMB) {
                        e(v_swrss, p_swrss);
-                       vp->v_minflt = u.u_vm.vm_minflt;
                        vp->v_majflt = u.u_vm.vm_majflt;
                        vp->v_majflt = u.u_vm.vm_majflt;
-                       if (mproc->p_textp) {
-                               xp = &text[mproc->p_textp -
-                                   (struct text *)nl[X_TEXT].n_value];
-                               vp->v_tsiz = xp->x_size;
-                               vp->v_txtrss = xp->x_rssize;
+                       if (mproc->p_textp)
                                vp->v_txtswrss = xp->x_swrss;
                                vp->v_txtswrss = xp->x_swrss;
-                               vp->v_xccount = xp->x_ccount;
-                       }
                }
                vp->v_pctcpu = pcpu();
 #undef e
                }
                vp->v_pctcpu = pcpu();
 #undef e
-       } else if (uflg)
-               sp->sun.u_pctcpu = pcpu();
-       else if (sflg) {
+       } else if (uflg) {
+               if (!ssflg)
+                       sp->sun.u_pctcpu = pcpu();
+               else {
+                       register struct sssav *ssp;
+
+                       sp->sun.ssp =ssp= (struct sssav *)alloc(sizeof (struct sssav));
+                       ssp->ss_ppid = mproc->p_ppid;
+               }
+       } else if (sflg) {
                if (ap->a_stat != SZOMB) {
                        for (cp = (char *)u.u_stack;
                if (ap->a_stat != SZOMB) {
                        for (cp = (char *)u.u_stack;
-                           cp < &user.upages[UPAGES][NBPG]; )
+                           cp < &user.upages[UPAGES][0]; )
                                if (*cp++)
                                        break;
                                if (*cp++)
                                        break;
-                       sp->sun.s_ssiz = (&user.upages[UPAGES][NBPG] - cp);
+                       sp->sun.s_ssiz = (&user.upages[UPAGES][0] - cp);
                }
        }
                }
        }
+
        npr++;
 }
 
        npr++;
 }
 
+double
+pmem(ap)
+       register struct asav *ap;
+{
+       double fracmem;
+       int szptudot;
+
+       if ((ap->a_flag&SLOAD) == 0)
+               fracmem = 0.0;
+       else {
+               szptudot = UPAGES + clrnd(ctopt(ap->a_size+ap->a_tsiz));
+               fracmem = ((float)ap->a_rss+szptudot)/CLSIZE/ecmx;
+               if (ap->a_xccount)
+                       fracmem += ((float)ap->a_txtrss)/CLSIZE/
+                           ap->a_xccount/ecmx;
+       }
+       return (100.0 * fracmem);
+}
+
 double
 pcpu()
 {
 double
 pcpu()
 {
+       time_t time;
 
 
-       if (mproc->p_time == 0 || (mproc->p_flag&SLOAD) == 0)
+       time = mproc->p_time;
+       if (time == 0 || (mproc->p_flag&SLOAD) == 0)
                return (0.0);
                return (0.0);
-       return (100.0 * mproc->p_pctcpu / (1.0 - exp(mproc->p_time * log(ccpu))));
+       if (rawcpu)
+               return (100.0 * mproc->p_pctcpu);
+       return (100.0 * mproc->p_pctcpu / (1.0 - exp(time * log(ccpu))));
 }
 
 getu()
 {
 }
 
 getu()
 {
-       struct pte *pteaddr, apte, arguutl[UPAGES+CLSIZE];
+       struct pte *pteaddr, apte;
+       struct pte arguutl[UPAGES+CLSIZE];
        register int i;
        int ncl, size;
 
        size = sflg ? ctob(UPAGES) : sizeof (struct user);
        if ((mproc->p_flag & SLOAD) == 0) {
        register int i;
        int ncl, size;
 
        size = sflg ? ctob(UPAGES) : sizeof (struct user);
        if ((mproc->p_flag & SLOAD) == 0) {
-               lseek(swap, ctob(mproc->p_swaddr), 0);
+               (void) lseek(swap, (long)ctob(mproc->p_swaddr), 0);
                if (read(swap, (char *)&user.user, size) != size) {
                        fprintf(stderr, "ps: cant read u for pid %d from %s\n",
                            mproc->p_pid, swapf);
                if (read(swap, (char *)&user.user, size) != size) {
                        fprintf(stderr, "ps: cant read u for pid %d from %s\n",
                            mproc->p_pid, swapf);
@@ -637,15 +755,18 @@ getu()
                argaddr = 0;
                return (1);
        }
                argaddr = 0;
                return (1);
        }
+       if (kflg)
+               mproc->p_p0br = (struct pte *)clear(mproc->p_p0br);
        pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
        pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
-       lseek(kmem, kflg ? clear(pteaddr) : (int)pteaddr, 0);
+       klseek(kmem, (long)pteaddr, 0);
        if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
                printf("ps: cant read indir pte to get u for pid %d from %s\n",
                    mproc->p_pid, swapf);
                return (0);
        }
        if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
                printf("ps: cant read indir pte to get u for pid %d from %s\n",
                    mproc->p_pid, swapf);
                return (0);
        }
-       lseek(mem,
-           ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte), 0);
+       (void) lseek(mem,
+           (long)ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte),
+               0);
        if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
                printf("ps: cant read page table for u of pid %d from %s\n",
                    mproc->p_pid, swapf);
        if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
                printf("ps: cant read page table for u of pid %d from %s\n",
                    mproc->p_pid, swapf);
@@ -659,7 +780,7 @@ getu()
        ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
        while (--ncl >= 0) {
                i = ncl * CLSIZE;
        ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
        while (--ncl >= 0) {
                i = ncl * CLSIZE;
-               lseek(mem, ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
+               (void) lseek(mem, (long)ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
                if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
                        printf("ps: cant read page %d of u of pid %d from %s\n",
                            arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
                if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
                        printf("ps: cant read page %d of u of pid %d from %s\n",
                            arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
@@ -686,17 +807,17 @@ getcmd()
        if (mproc->p_stat == SZOMB || mproc->p_flag&(SSYS|SWEXIT))
                return ("");
        if (cflg) {
        if (mproc->p_stat == SZOMB || mproc->p_flag&(SSYS|SWEXIT))
                return ("");
        if (cflg) {
-               strncpy(cmdbuf, u.u_comm, sizeof (u.u_comm));
+               (void) strncpy(cmdbuf, u.u_comm, sizeof (u.u_comm));
                return (savestr(cmdbuf));
        }
        if ((mproc->p_flag & SLOAD) == 0 || argaddr == 0) {
                vstodb(0, CLSIZE, &u.u_smap, &db, 1);
                return (savestr(cmdbuf));
        }
        if ((mproc->p_flag & SLOAD) == 0 || argaddr == 0) {
                vstodb(0, CLSIZE, &u.u_smap, &db, 1);
-               lseek(swap, ctob(db.db_base), 0);
+               (void) lseek(swap, (long)ctob(db.db_base), 0);
                if (read(swap, (char *)&argspac, sizeof(argspac))
                    != sizeof(argspac))
                        goto bad;
        } else {
                if (read(swap, (char *)&argspac, sizeof(argspac))
                    != sizeof(argspac))
                        goto bad;
        } else {
-               lseek(mem, argaddr, 0);
+               (void) lseek(mem, (long)argaddr, 0);
                if (read(mem, (char *)&argspac, sizeof (argspac))
                    != sizeof (argspac))
                        goto bad;
                if (read(mem, (char *)&argspac, sizeof (argspac))
                    != sizeof (argspac))
                        goto bad;
@@ -730,11 +851,11 @@ getcmd()
        while (*--cp == ' ')
                *cp = 0;
        cp = (char *)ip;
        while (*--cp == ' ')
                *cp = 0;
        cp = (char *)ip;
-       strncpy(cmdbuf, cp, &argspac.argc[CLSIZE*NBPG] - cp);
+       (void) strncpy(cmdbuf, cp, &argspac.argc[CLSIZE*NBPG] - cp);
        if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
        if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
-               strcat(cmdbuf, " (");
-               strncat(cmdbuf, u.u_comm, sizeof(u.u_comm));
-               strcat(cmdbuf, ")");
+               (void) strcat(cmdbuf, " (");
+               (void) strncat(cmdbuf, u.u_comm, sizeof(u.u_comm));
+               (void) strcat(cmdbuf, ")");
        }
 /*
        if (xflg == 0 && gflg == 0 && tptr == 0 && cp[0] == '-')
        }
 /*
        if (xflg == 0 && gflg == 0 && tptr == 0 && cp[0] == '-')
@@ -746,14 +867,14 @@ bad:
        fprintf(stderr, "ps: error locating command name for pid %d\n",
            mproc->p_pid);
 retucomm:
        fprintf(stderr, "ps: error locating command name for pid %d\n",
            mproc->p_pid);
 retucomm:
-       strcpy(cmdbuf, " (");
-       strncat(cmdbuf, u.u_comm, sizeof (u.u_comm));
-       strcat(cmdbuf, ")");
+       (void) strcpy(cmdbuf, " (");
+       (void) strncat(cmdbuf, u.u_comm, sizeof (u.u_comm));
+       (void) strcat(cmdbuf, ")");
        return (savestr(cmdbuf));
 }
 
 char   *lhdr =
        return (savestr(cmdbuf));
 }
 
 char   *lhdr =
-"     F UID   PID  PPID CP PRI NI ADDR  SZ  RSS WCHAN ST TT  TIME";
+"     F UID   PID  PPID CP PRI NI ADDR  SZ  RSS WCHAN STAT TT  TIME";
 lpr(sp)
        struct savcom *sp;
 {
 lpr(sp)
        struct savcom *sp;
 {
@@ -765,7 +886,7 @@ lpr(sp)
            ap->a_pid, lp->l_ppid, lp->l_cpu&0377, ap->a_pri-PZERO,
            ap->a_nice-NZERO, lp->l_addr, ap->a_size/2, ap->a_rss/2);
        printf(lp->l_wchan ? " %5x" : "      ", (int)lp->l_wchan&0xfffff);
            ap->a_pid, lp->l_ppid, lp->l_cpu&0377, ap->a_pri-PZERO,
            ap->a_nice-NZERO, lp->l_addr, ap->a_size/2, ap->a_rss/2);
        printf(lp->l_wchan ? " %5x" : "      ", (int)lp->l_wchan&0xfffff);
-       printf(" %2.2s ", state(ap));
+       printf(" %4.4s ", state(ap));
        ptty(ap->a_tty);
        ptime(ap);
 }
        ptty(ap->a_tty);
        ptime(ap);
 }
@@ -781,45 +902,56 @@ ptime(ap)
        struct asav *ap;
 {
 
        struct asav *ap;
 {
 
-       printf("%3ld:%02ld", ap->a_cpu / HZ, ap->a_cpu % HZ);
+       printf("%3ld:%02ld", ap->a_cpu / hz, ap->a_cpu % hz);
 }
 
 char   *uhdr =
 }
 
 char   *uhdr =
-"USER       PID %CPU NI   SZ  RSS TT ST  TIME";
+"USER       PID %CPU %MEM   SZ  RSS TT STAT  TIME";
 upr(sp)
        struct savcom *sp;
 {
        register struct asav *ap = sp->ap;
 upr(sp)
        struct savcom *sp;
 {
        register struct asav *ap = sp->ap;
-
-       printf("%-8.8s %5u%5.1f%3d%5d%5d",
-           getname(ap->a_uid), ap->a_pid, sp->sun.u_pctcpu, ap->a_nice-NZERO,
-           ap->a_size/2, ap->a_rss/2);
+       int vmsize, rmsize;
+
+       vmsize = (ap->a_size + ap->a_tsiz)/2;
+       rmsize = ap->a_rss/2;
+       if (ap->a_xccount)
+               rmsize += ap->a_txtrss/ap->a_xccount/2;
+       printf("%-8.8s %5d%5.1f%5.1f%5d%5d",
+           getname(ap->a_uid), ap->a_pid, sp->sun.u_pctcpu, pmem(ap),
+           vmsize, rmsize);
        putchar(' ');
        ptty(ap->a_tty);
        putchar(' ');
        ptty(ap->a_tty);
-       printf(" %2.2s", state(ap));
+       printf(" %4.4s", state(ap));
        ptime(ap);
 }
 
 char *vhdr =
        ptime(ap);
 }
 
 char *vhdr =
-"   PID TT ST    TIME RES SL MINFLT MAJFLT SIZE  RSS  SRS TSIZ TRS %CP";
+"  PID TT STAT  TIME SL RE PAGEIN SIZE  RSS  LIM TSIZ TRS %CPU %MEM";
 vpr(sp)
        struct savcom *sp;
 {
        register struct vsav *vp = sp->sun.vp;
        register struct asav *ap = sp->ap;
 
 vpr(sp)
        struct savcom *sp;
 {
        register struct vsav *vp = sp->sun.vp;
        register struct asav *ap = sp->ap;
 
-       printf("%6u ", ap->a_pid);
+       printf("%5u ", ap->a_pid);
        ptty(ap->a_tty);
        ptty(ap->a_tty);
-       printf(" %4s", state(ap));
+       printf(" %4.4s", state(ap));
        ptime(ap);
        ptime(ap);
-       printf("%4d%3d%7d%7d%5d%5d%5d%5d%4d%4d",
-          ap->a_time, ap->a_slptime, vp->v_minflt, vp->v_majflt,
-          ap->a_size/2, ap->a_rss/2, vp->v_swrss/2,
-          vp->v_tsiz/2, vp->v_txtrss/2, vp->v_pctcpu);
+       printf("%3d%3d%7d%5d%5d",
+          ap->a_slptime > 99 ? 99 : ap-> a_slptime,
+          ap->a_time > 99 ? 99 : ap->a_time, vp->v_majflt,
+          ap->a_size/2, ap->a_rss/2);
+       if (ap->a_maxrss == (INFINITY/NBPG))
+               printf("   xx");
+       else
+               printf("%5d", ap->a_maxrss/2);
+       printf("%5d%4d%5.1f%5.1f",
+          ap->a_tsiz/2, ap->a_txtrss/2, vp->v_pctcpu, pmem(ap));
 }
 
 char   *shdr =
 }
 
 char   *shdr =
-"SSIZ   PID TT ST  TIME";
+"SSIZ   PID TT STAT  TIME";
 spr(sp)
        struct savcom *sp;
 {
 spr(sp)
        struct savcom *sp;
 {
@@ -830,7 +962,7 @@ spr(sp)
        printf("%5u", ap->a_pid);
        putchar(' ');
        ptty(ap->a_tty);
        printf("%5u", ap->a_pid);
        putchar(' ');
        ptty(ap->a_tty);
-       printf(" %2.2s", state(ap));
+       printf(" %4.4s", state(ap));
        ptime(ap);
 }
 
        ptime(ap);
 }
 
@@ -872,9 +1004,14 @@ state(ap)
        default:
                stat = '?';
        }
        default:
                stat = '?';
        }
-       load = ap->a_flag & SLOAD ? ' ' : 'W';
-       nice = ap->a_nice > NZERO ? 'N' : ' ';
-       anom = ap->a_flag & (SANOM|SUANOM) ? 'A' : ' ';
+       load = ap->a_flag & SLOAD ? (ap->a_rss>ap->a_maxrss ? '>' : ' ') : 'W';
+       if (ap->a_nice < NZERO)
+               nice = '<';
+       else if (ap->a_nice > NZERO)
+               nice = 'N';
+       else
+               nice = ' ';
+       anom = (ap->a_flag&SUANOM) ? 'A' : ((ap->a_flag&SSEQL) ? 'S' : ' ');
        res[0] = stat; res[1] = load; res[2] = nice; res[3] = anom;
        return (res);
 }
        res[0] = stat; res[1] = load; res[2] = nice; res[3] = anom;
        return (res);
 }
@@ -928,7 +1065,7 @@ pscomp(s1, s2)
 {
        register int i;
 
 {
        register int i;
 
-       if (uflg)
+       if (uflg && !ssflg)
                return (s2->sun.u_pctcpu > s1->sun.u_pctcpu ? 1 : -1);
        if (vflg)
                return (vsize(s2) - vsize(s1));
                return (s2->sun.u_pctcpu > s1->sun.u_pctcpu ? 1 : -1);
        if (vflg)
                return (vsize(s2) - vsize(s1));
@@ -946,8 +1083,8 @@ vsize(sp)
        
        if (ap->a_flag & SLOAD)
                return (ap->a_rss +
        
        if (ap->a_flag & SLOAD)
                return (ap->a_rss +
-                   vp->v_txtrss / (vp->v_xccount ? vp->v_xccount : 1));
-       return (vp->v_swrss + (vp->v_xccount ? 0 : vp->v_txtswrss));
+                   ap->a_txtrss / (ap->a_xccount ? ap->a_xccount : 1));
+       return (vp->v_swrss + (ap->a_xccount ? 0 : vp->v_txtswrss));
 }
 
 #define        NMAX    8
 }
 
 #define        NMAX    8
@@ -965,7 +1102,7 @@ getname(uid)
        static init;
        struct passwd *getpwent();
 
        static init;
        struct passwd *getpwent();
 
-       if (names[uid][0])
+       if (uid >= 0 && uid < NUID && names[uid][0])
                return (&names[uid][0]);
        if (init == 2)
                return (0);
                return (&names[uid][0]);
        if (init == 2)
                return (0);
@@ -976,7 +1113,7 @@ getname(uid)
                        continue;
                if (names[pw->pw_uid][0])
                        continue;
                        continue;
                if (names[pw->pw_uid][0])
                        continue;
-               strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
+               (void) strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
                if (pw->pw_uid == uid)
                        return (&names[uid][0]);
        }
                if (pw->pw_uid == uid)
                        return (&names[uid][0]);
        }
@@ -996,7 +1133,7 @@ alloc(size)
        register int i;
 
        if (size > nleft) {
        register int i;
 
        if (size > nleft) {
-               freebase = (char *)sbrk(i = size > 2048 ? size : 2048);
+               freebase = (char *)sbrk((int)(i = size > 2048 ? size : 2048));
                if (freebase == 0) {
                        fprintf(stderr, "ps: ran out of memory\n");
                        exit(1);
                if (freebase == 0) {
                        fprintf(stderr, "ps: ran out of memory\n");
                        exit(1);
@@ -1020,6 +1157,93 @@ savestr(cp)
 
        len = strlen(cp);
        dp = (char *)alloc(len+1);
 
        len = strlen(cp);
        dp = (char *)alloc(len+1);
-       strcpy(dp, cp);
+       (void) strcpy(dp, cp);
        return (dp);
 }
        return (dp);
 }
+
+walk(np)
+       int np;
+{
+       register int i, j, k, l, m;
+#undef afl
+#undef sfl
+#define afl(i,f) savcom[i].ap -> f
+#define sfl(i,f) savcom[i].sun.ssp -> f
+
+       for(i = 0; i < np; i = j) {
+               for(j = i; afl(j,a_ttyd) == afl(i,a_ttyd); j++) {
+                       sfl(j,ss_brother) = -1;
+                       sfl(j,ss_sons) = -1;
+               }
+               for(k = i+1; k < j; k++) {
+                       if(sfl(k,ss_ppid) == sfl(i,ss_ppid)) {
+                               for(l=i; sfl(l,ss_brother) != -1; 
+                                       l=sfl(l,ss_brother)) ;
+                               sfl(l,ss_brother) = k;
+                               goto next;
+                       }
+                       for(l = i; l < j; l++) {
+                               if(l == k) continue;
+                               if(sfl(k,ss_ppid) == afl(l,a_pid)) {
+                                       if(sfl(l,ss_sons) == -1)
+                                           sfl(l,ss_sons) = k;
+                                       else {
+                                           for(m = sfl(l,ss_sons);
+                                               sfl(m,ss_brother) != -1;
+                                               m = sfl(m,ss_brother)) ;
+                                           sfl(m,ss_brother) = k;
+                                       }
+                                       goto next;
+                               }
+                       }
+                       for(l = i; l < j; l++) {
+                               if(l == k) continue;
+                               if(sfl(k,ss_ppid) == sfl(l,ss_ppid)) {
+                                       for(m = k; sfl(m,ss_brother) != -1;
+                                           m = sfl(m,ss_brother)) ;
+                                       sfl(m,ss_brother) = l;
+                               }
+                       }
+               next: ;
+               }
+               walk1(i, 0);
+       }
+}
+
+walk1(pno, depth)
+       int pno, depth;
+{
+       if(pno == -1)
+               return;
+/***    printf("%5d, %d\n",outargs[pno].o_pid, depth);  ***/
+       walkpr(&savcom[pno], depth);
+       walk1(sfl(pno,ss_sons), depth+1);
+       walk1(sfl(pno,ss_brother), depth);
+}
+
+char *sshdr =
+"TTY User     SZ RSS  CPU  S      PID  ";
+
+walkpr(a, depth)
+       register struct savcom *a;
+       int depth;
+{
+
+       if(!depth) {
+               printf("%-2.2s", a->ap->a_tty);
+               printf(" %-8.8s", getname(a->ap->a_uid));
+       } else
+               printf("   %-8s", &".......*"[8-(depth<=8?depth:8)]);
+       printf("%4d%4d", a->ap->a_size/2, a->ap->a_rss/2);
+       ptime(a->ap);
+       /* Once there was a "CCPU" field here.  Subsumed by -S now. */
+       printf(" %4.4s", state(a->ap));
+       printf("%6u ", a->ap->a_pid);
+       if (a->ap->a_pid == 0)
+               printf(" swapper");
+       else if (a->ap->a_pid == 2)
+               printf(" pagedaemon");
+       else
+               printf(" %.*s", twidth - cmdstart - 2, a->ap->a_cmdp);
+       putchar('\n');
+}