Author: brian
Date: Sun Jun  7 08:11:25 2009
New Revision: 193626
URL: http://svn.freebsd.org/changeset/base/193626

Log:
  MFC: r192239: Add a -d switch.

Modified:
  stable/7/bin/ps/   (props changed)
  stable/7/bin/ps/print.c
  stable/7/bin/ps/ps.1
  stable/7/bin/ps/ps.c
  stable/7/bin/ps/ps.h

Modified: stable/7/bin/ps/print.c
==============================================================================
--- stable/7/bin/ps/print.c     Sun Jun  7 07:45:25 2009        (r193625)
+++ stable/7/bin/ps/print.c     Sun Jun  7 08:11:25 2009        (r193626)
@@ -129,25 +129,33 @@ command(KINFO *k, VARENT *ve)
        v = ve->var;
        if (cflag) {
                /* If it is the last field, then don't pad */
-               if (STAILQ_NEXT(ve, next_ve) == NULL)
+               if (STAILQ_NEXT(ve, next_ve) == NULL) {
+                       if (k->ki_d.prefix)
+                               (void)printf("%s", k->ki_d.prefix);
                        (void)printf("%s", k->ki_p->ki_comm);
-               else
+               } else
                        (void)printf("%-*s", v->width, k->ki_p->ki_comm);
                return;
        }
        if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL)
                errx(1, "malloc failed");
        strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH);
-       if (k->ki_env) {
-               if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) == NULL)
-                       errx(1, "malloc failed");
-               strvis(vis_env, k->ki_env, VIS_TAB | VIS_NL | VIS_NOSLASH);
-       } else
-               vis_env = NULL;
 
        if (STAILQ_NEXT(ve, next_ve) == NULL) {
                /* last field */
+
+               if (k->ki_env) {
+                       if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1))
+                           == NULL)
+                               errx(1, "malloc failed");
+                       strvis(vis_env, k->ki_env,
+                           VIS_TAB | VIS_NL | VIS_NOSLASH);
+               } else
+                       vis_env = NULL;
+
                if (termwidth == UNLIMITED) {
+                       if (k->ki_d.prefix)
+                               (void)printf("%s", k->ki_d.prefix);
                        if (vis_env)
                                (void)printf("%s ", vis_env);
                        (void)printf("%s", vis_args);
@@ -155,6 +163,9 @@ command(KINFO *k, VARENT *ve)
                        left = termwidth - (totwidth - v->width);
                        if (left < 1) /* already wrapped, just use std width */
                                left = v->width;
+                       if ((cp = k->ki_d.prefix) != NULL)
+                               while (--left >= 0 && *cp)
+                                       (void)putchar(*cp++);
                        if ((cp = vis_env) != NULL) {
                                while (--left >= 0 && *cp)
                                        (void)putchar(*cp++);
@@ -164,12 +175,12 @@ command(KINFO *k, VARENT *ve)
                        for (cp = vis_args; --left >= 0 && *cp != '\0';)
                                (void)putchar(*cp++);
                }
+               if (vis_env != NULL)
+                       free(vis_env);
        } else
-               /* XXX env? */
+               /* ki_d.prefix & ki_env aren't shown for interim fields */
                (void)printf("%-*.*s", v->width, v->width, vis_args);
        free(vis_args);
-       if (vis_env != NULL)
-               free(vis_env);
 }
 
 void
@@ -178,9 +189,11 @@ ucomm(KINFO *k, VARENT *ve)
        VAR *v;
 
        v = ve->var;
-       if (STAILQ_NEXT(ve, next_ve) == NULL)   /* last field, don't pad */
+       if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field, don't pad */
+               if (k->ki_d.prefix)
+                       (void)printf("%s", k->ki_d.prefix);
                (void)printf("%s", k->ki_p->ki_comm);
-       else
+       } else
                (void)printf("%-*s", v->width, k->ki_p->ki_comm);
 }
 

Modified: stable/7/bin/ps/ps.1
==============================================================================
--- stable/7/bin/ps/ps.1        Sun Jun  7 07:45:25 2009        (r193625)
+++ stable/7/bin/ps/ps.1        Sun Jun  7 08:11:25 2009        (r193626)
@@ -29,7 +29,7 @@
 .\"     @(#)ps.1       8.3 (Berkeley) 4/18/94
 .\" $FreeBSD$
 .\"
-.Dd August 21, 2006
+.Dd May 16, 2009
 .Dt PS 1
 .Os
 .Sh NAME
@@ -37,7 +37,7 @@
 .Nd process status
 .Sh SYNOPSIS
 .Nm
-.Op Fl aCcefHhjlmrSTuvwXxZ
+.Op Fl aCcdefHhjlmrSTuvwXxZ
 .Op Fl O Ar fmt | Fl o Ar fmt
 .Op Fl G Ar gid Ns Op , Ns Ar gid Ns Ar ...
 .Op Fl M Ar core
@@ -122,6 +122,15 @@ CPU calculation that ignores
 .Dq resident
 time (this normally has
 no effect).
+.It Fl d
+Arrange processes into descendancy order and prefix each command with
+indentation text showing sibling and parent/child relationships.
+If either of the
+.Fl m
+and
+.Fl r
+options are also used, they control how sibling processes are sorted
+relative to eachother.
 .It Fl e
 Display the environment as well.
 .It Fl f

Modified: stable/7/bin/ps/ps.c
==============================================================================
--- stable/7/bin/ps/ps.c        Sun Jun  7 07:45:25 2009        (r193625)
+++ stable/7/bin/ps/ps.c        Sun Jun  7 08:11:25 2009        (r193626)
@@ -137,6 +137,7 @@ static int   addelem_pid(struct listinfo 
 static int      addelem_tty(struct listinfo *, const char *);
 static int      addelem_uid(struct listinfo *, const char *);
 static void     add_list(struct listinfo *, const char *);
+static void     descendant_sort(KINFO *, int);
 static void     dynsizevars(KINFO *);
 static void    *expand_list(struct listinfo *);
 static const char *
@@ -162,7 +163,7 @@ static char vfmt[] = "pid,state,time,sl,
                        "%cpu,%mem,command";
 static char Zfmt[] = "label";
 
-#define        PS_ARGS "AaCce" OPT_LAZY_f "G:gHhjLlM:mN:O:o:p:rSTt:U:uvwXxZ"
+#define        PS_ARGS "AaCcde" OPT_LAZY_f "G:gHhjLlM:mN:O:o:p:rSTt:U:uvwXxZ"
 
 int
 main(int argc, char *argv[])
@@ -176,7 +177,7 @@ main(int argc, char *argv[])
        const char *nlistf, *memf;
        char *cols;
        int all, ch, elem, flag, _fmt, i, lineno;
-       int nentries, nkept, nselectors;
+       int descendancy, nentries, nkept, nselectors;
        int prtheader, showthreads, wflag, what, xkeep, xkeep_implied;
        char errbuf[_POSIX2_LINE_MAX];
 
@@ -200,7 +201,7 @@ main(int argc, char *argv[])
        if (argc > 1)
                argv[1] = kludge_oldps_options(PS_ARGS, argv[1], argv[2]);
 
-       all = _fmt = nselectors = optfatal = 0;
+       all = descendancy = _fmt = nselectors = optfatal = 0;
        prtheader = showthreads = wflag = xkeep_implied = 0;
        xkeep = -1;                     /* Neither -x nor -X. */
        init_list(&gidlist, addelem_gid, sizeof(gid_t), "group");
@@ -232,6 +233,9 @@ main(int argc, char *argv[])
                case 'c':
                        cflag = 1;
                        break;
+               case 'd':
+                       descendancy = 1;
+                       break;
                case 'e':                       /* XXX set ufmt */
                        needenv = 1;
                        break;
@@ -574,6 +578,8 @@ main(int argc, char *argv[])
                keepit:
                        next_KINFO = &kinfo[nkept];
                        next_KINFO->ki_p = kp;
+                       next_KINFO->ki_d.level = 0;
+                       next_KINFO->ki_d.prefix = NULL;
                        next_KINFO->ki_pcpu = getpcpu(next_KINFO);
                        if (sortby == SORTMEM)
                                next_KINFO->ki_memsize = kp->ki_tsize +
@@ -598,6 +604,13 @@ main(int argc, char *argv[])
         * sort proc list
         */
        qsort(kinfo, nkept, sizeof(KINFO), pscomp);
+
+       /*
+        * We want things in descendant order
+        */
+       if (descendancy)
+               descendant_sort(kinfo, nkept);
+
        /*
         * For each process, call each variable output function.
         */
@@ -621,6 +634,9 @@ main(int argc, char *argv[])
        free_list(&sesslist);
        free_list(&ttylist);
        free_list(&uidlist);
+       for (i = 0; i < nkept; i++)
+               free(kinfo[i].ki_d.prefix);
+       free(kinfo);
 
        exit(eval);
 }
@@ -889,6 +905,116 @@ add_list(struct listinfo *inf, const cha
        }
 }
 
+static void
+descendant_sort(KINFO *ki, int items)
+{
+       int dst, lvl, maxlvl, n, ndst, nsrc, siblings, src;
+       unsigned char *path;
+       KINFO kn;
+
+       /*
+        * First, sort the entries by descendancy, tracking the descendancy
+        * depth in the ki_d.level field.
+        */
+       src = 0;
+       maxlvl = 0;
+       while (src < items) {
+               if (ki[src].ki_d.level) {
+                       src++;
+                       continue;
+               }
+               for (nsrc = 1; src + nsrc < items; nsrc++)
+                       if (!ki[src + nsrc].ki_d.level)
+                               break;
+
+               for (dst = 0; dst < items; dst++) {
+                       if (ki[dst].ki_p->ki_pid == ki[src].ki_p->ki_pid)
+                               continue;
+                       if (ki[dst].ki_p->ki_pid == ki[src].ki_p->ki_ppid)
+                               break;
+               }
+
+               if (dst == items) {
+                       src += nsrc;
+                       continue;
+               }
+
+               for (ndst = 1; dst + ndst < items; ndst++)
+                       if (ki[dst + ndst].ki_d.level <= ki[dst].ki_d.level)
+                               break;
+
+               for (n = src; n < src + nsrc; n++) {
+                       ki[n].ki_d.level += ki[dst].ki_d.level + 1;
+                       if (maxlvl < ki[n].ki_d.level)
+                               maxlvl = ki[n].ki_d.level;
+               }
+
+               while (nsrc) {
+                       if (src < dst) {
+                               kn = ki[src];
+                               memmove(ki + src, ki + src + 1,
+                                   (dst - src + ndst - 1) * sizeof *ki);
+                               ki[dst + ndst - 1] = kn;
+                               nsrc--;
+                               dst--;
+                               ndst++;
+                       } else if (src != dst + ndst) {
+                               kn = ki[src];
+                               memmove(ki + dst + ndst + 1, ki + dst + ndst,
+                                   (src - dst - ndst) * sizeof *ki);
+                               ki[dst + ndst] = kn;
+                               ndst++;
+                               nsrc--;
+                               src++;
+                       } else {
+                               ndst += nsrc;
+                               src += nsrc;
+                               nsrc = 0;
+                       }
+               }
+       }
+
+       /*
+        * Now populate ki_d.prefix (instead of ki_d.level) with the command
+        * prefix used to show descendancies.
+        */
+       path = malloc((maxlvl + 7) / 8);
+       memset(path, '\0', (maxlvl + 7) / 8);
+       for (src = 0; src < items; src++) {
+               if ((lvl = ki[src].ki_d.level) == 0) {
+                       ki[src].ki_d.prefix = NULL;
+                       continue;
+               }
+               if ((ki[src].ki_d.prefix = malloc(lvl * 2 + 1)) == NULL)
+                       errx(1, "malloc failed");
+               for (n = 0; n < lvl - 2; n++) {
+                       ki[src].ki_d.prefix[n * 2] =
+                           path[n / 8] & 1 << (n % 8) ? '|' : ' ';
+                       ki[src].ki_d.prefix[n * 2 + 1] = ' ';
+                               
+               }
+               if (n == lvl - 2) {
+                       /* Have I any more siblings? */
+                       for (siblings = 0, dst = src + 1; dst < items; dst++) {
+                               if (ki[dst].ki_d.level > lvl)
+                                       continue;
+                               if (ki[dst].ki_d.level == lvl)
+                                       siblings = 1;
+                               break;
+                       }
+                       if (siblings)
+                               path[n / 8] |= 1 << (n % 8);
+                       else
+                               path[n / 8] &= ~(1 << (n % 8));
+                       ki[src].ki_d.prefix[n * 2] = siblings ? '|' : '`';
+                       ki[src].ki_d.prefix[n * 2 + 1] = '-';
+                       n++;
+               }
+               strcpy(ki[src].ki_d.prefix + n * 2, "- ");
+       }
+       free(path);
+}
+
 static void *
 expand_list(struct listinfo *inf)
 {

Modified: stable/7/bin/ps/ps.h
==============================================================================
--- stable/7/bin/ps/ps.h        Sun Jun  7 07:45:25 2009        (r193625)
+++ stable/7/bin/ps/ps.h        Sun Jun  7 08:11:25 2009        (r193626)
@@ -42,6 +42,10 @@ typedef struct kinfo {
        int ki_valid;           /* 1 => uarea stuff valid */
        double   ki_pcpu;       /* calculated in main() */
        segsz_t  ki_memsize;    /* calculated in main() */
+       union {
+               int level;      /* used in decendant_sort() */
+               char *prefix;   /* calculated in decendant_sort() */
+       } ki_d;
 } KINFO;
 
 /* Variables. */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to