home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / bin / ps / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-01  |  12.4 KB  |  601 lines

  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, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)print.c    5.9 (Berkeley) 7/1/91";
  36. #endif /* not lint */
  37.  
  38. #include <sys/param.h>
  39. #include <sys/time.h>
  40. #include <sys/resource.h>
  41. #include <sys/proc.h>
  42. #include <sys/stat.h>
  43. #include <math.h>
  44. #include <tzfile.h>
  45. #include <stddef.h>
  46. #include <string.h>
  47. #include "ps.h"
  48.  
  49. #ifdef SPPWAIT
  50. #define NEWVM
  51. #endif
  52.  
  53. #ifdef NEWVM
  54. #include <vm/vm.h>
  55. #include <sys/ucred.h>
  56. #include <sys/kinfo_proc.h>
  57. #else
  58. #include <machine/pte.h>
  59. #include <sys/vmparam.h>
  60. #include <sys/vm.h>
  61. #endif
  62.  
  63. printheader()
  64. {
  65.     register VAR *v;
  66.     register struct varent *vent;
  67.  
  68.     for (vent = vhead; vent; vent = vent->next) {
  69.         v = vent->var;
  70.         if (v->flag & LJUST) {
  71.             if (vent->next == NULL)    /* last one */
  72.                 (void) printf("%s", v->header);
  73.             else
  74.                 (void) printf("%-*s", v->width, v->header);
  75.         } else
  76.             (void) printf("%*s", v->width, v->header);
  77.         if (vent->next != NULL)
  78.             (void) putchar(' ');
  79.     }
  80.     (void) putchar('\n');
  81. }
  82.  
  83. command(k, v, next)
  84.     KINFO *k;
  85.     VAR *v;
  86. {
  87.     extern int termwidth, totwidth;
  88.  
  89.     if (next == NULL) {
  90.         /* last field */
  91.         if (termwidth == UNLIMITED)
  92.             (void) printf("%s", k->ki_args);
  93.         else {
  94.             register int left = termwidth - (totwidth - v->width);
  95.             register char *cp = k->ki_args;
  96.  
  97.             if (left < 1) /* already wrapped, just use std width */
  98.                 left = v->width;
  99.             while (--left >= 0 && *cp)
  100.                 (void) putchar(*cp++);
  101.         }
  102.     } else
  103.         (void) printf("%-*.*s", v->width, v->width, k->ki_args);
  104.  
  105. }
  106.  
  107. ucomm(k, v)
  108.     KINFO *k;
  109.     VAR *v;
  110. {
  111.     (void) printf("%-*s", v->width, k->ki_p->p_comm);
  112. }
  113.  
  114. logname(k, v)
  115.     KINFO *k;
  116.     VAR *v;
  117. {
  118. #ifndef NEWVM
  119.     (void) printf("%-*s", v->width, k->ki_p->p_logname);
  120. #else /* NEWVM */
  121.     (void) printf("%-*s", v->width, k->ki_e->e_login);
  122. #endif /* NEWVM */
  123. }
  124.  
  125. state(k, v)
  126.     KINFO *k;
  127.     VAR *v;
  128. {
  129.     char buf[16];
  130.     register char *cp = buf;
  131.     register struct proc *p = k->ki_p;
  132.     register flag = p->p_flag;
  133.  
  134.     switch (p->p_stat) {
  135.  
  136.     case SSTOP:
  137.         *cp = 'T';
  138.         break;
  139.  
  140.     case SSLEEP:
  141.         if (flag & SSINTR)    /* interuptable (long) */
  142.             *cp = p->p_slptime >= MAXSLP ? 'I' : 'S';
  143.         else
  144.             *cp = (flag & SPAGE) ? 'P' : 'D';
  145.         break;
  146.  
  147.     case SRUN:
  148.     case SIDL:
  149.         *cp = 'R';
  150.         break;
  151.  
  152.     case SZOMB:
  153.         *cp = 'Z';
  154.         break;
  155.  
  156.     default:
  157.         *cp = '?';
  158.     }
  159.     cp++;
  160.     if (flag & SLOAD) {
  161. #ifndef NEWVM
  162.         if (p->p_rssize > p->p_maxrss)
  163.             *cp++ = '>';
  164. #endif
  165.     } else
  166.         *cp++ = 'W';
  167.     if (p->p_nice < NZERO)
  168.         *cp++ = '<';
  169.     else if (p->p_nice > NZERO)
  170.         *cp++ = 'N';
  171. #ifndef NEWVM
  172.     if (flag & SUANOM)
  173.         *cp++ = 'A';
  174.     else if (flag & SSEQL)
  175.         *cp++ = 'S';
  176. #endif
  177.     if (flag & STRC)
  178.         *cp++ = 'X';
  179.     if (flag & SWEXIT && p->p_stat != SZOMB)
  180.         *cp++ = 'E';
  181. #ifdef NEWVM
  182.     if (flag & SPPWAIT)
  183. #else
  184.     if (flag & SVFORK)
  185. #endif
  186.         *cp++ = 'V';
  187. #ifdef NEWVM
  188.     if (flag & (SSYS|SLOCK|SKEEP|SPHYSIO))
  189. #else
  190.     if (flag & (SSYS|SLOCK|SULOCK|SKEEP|SPHYSIO))
  191. #endif
  192.         *cp++ = 'L';
  193.     if (k->ki_e->e_flag & EPROC_SLEADER)
  194.         *cp++ = 's';
  195.     if ((flag & SCTTY) && k->ki_e->e_pgid == k->ki_e->e_tpgid)
  196.         *cp++ = '+';
  197.     *cp = '\0';
  198.     (void) printf("%-*s", v->width, buf);
  199. }
  200.  
  201. pri(k, v)
  202.     KINFO *k;
  203.     VAR *v;
  204. {
  205.     (void) printf("%*d", v->width, k->ki_p->p_pri - PZERO);
  206. }
  207.  
  208. uname(k, v)
  209.     KINFO *k;
  210.     VAR *v;
  211. {
  212. #ifndef NEWVM
  213.     (void) printf("%-*s", v->width, user_from_uid(k->ki_p->p_uid, 0));
  214. #else /* NEWVM */
  215.     (void) printf("%-*s", v->width,
  216.         user_from_uid(k->ki_e->e_ucred.cr_uid, 0));
  217. #endif /* NEWVM */
  218. }
  219.  
  220. runame(k, v)
  221.     KINFO *k;
  222.     VAR *v;
  223. {
  224. #ifndef NEWVM
  225.     (void) printf("%-*s", v->width, user_from_uid(k->ki_p->p_ruid, 0));
  226. #else /* NEWVM */
  227.     (void) printf("%-*s", v->width,
  228.         user_from_uid(k->ki_e->e_pcred.p_ruid, 0));
  229. #endif /* NEWVM */
  230. }
  231.  
  232. tdev(k, v)
  233.     KINFO *k;
  234.     VAR *v;
  235. {
  236.     dev_t dev = k->ki_e->e_tdev;
  237.  
  238.     if (dev == NODEV)
  239.         (void) printf("%*s", v->width, "??");
  240.     else {
  241.         char buff[16];
  242.  
  243.         (void) sprintf(buff, "%d/%d", major(dev), minor(dev));
  244.         (void) printf("%*s", v->width, buff);
  245.     }
  246. }
  247.  
  248. tname(k, v)
  249.     KINFO *k;
  250.     VAR *v;
  251. {
  252.     dev_t dev;
  253.     char *ttname, *devname();
  254.  
  255.     dev = k->ki_e->e_tdev;
  256.     if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
  257.         (void) printf("%-*s", v->width, "??");
  258.     else {
  259.         if (strncmp(ttname, "tty", 3) == 0)
  260.             ttname += 3;
  261.         (void) printf("%*.*s%c", v->width-1, v->width-1, ttname,
  262.             k->ki_e->e_flag & EPROC_CTTY ? ' ' : '-');
  263.     }
  264. }
  265.  
  266. longtname(k, v)
  267.     KINFO *k;
  268.     VAR *v;
  269. {
  270.     dev_t dev;
  271.     char *ttname, *devname();
  272.  
  273.     dev = k->ki_e->e_tdev;
  274.     if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
  275.         (void) printf("%-*s", v->width, "??");
  276.     else
  277.         (void) printf("%-*s", v->width, ttname);
  278. }
  279.  
  280. started(k, v)
  281.     KINFO *k;
  282.     VAR *v;
  283. {
  284.     static time_t now;
  285.     struct tm *tp;
  286.     char buf[100];
  287.  
  288.     if (!k->ki_u) {
  289.         (void) printf("%-*s", v->width, "-");
  290.         return;
  291.     }
  292.  
  293.     tp = localtime(&k->ki_u->u_start.tv_sec);
  294.     if (!now)
  295.         (void)time(&now);
  296.     if (now - k->ki_u->u_start.tv_sec < 24 * SECSPERHOUR) {
  297.         static char fmt[] = "%l:@M%p";
  298.         fmt[3] = '%';            /* I *hate* SCCS... */
  299.         (void) strftime(buf, sizeof(buf) - 1, fmt, tp);
  300.     } else if (now - k->ki_u->u_start.tv_sec < 7 * SECSPERDAY) {
  301.         static char fmt[] = "%a@I%p";
  302.         fmt[2] = '%';            /* I *hate* SCCS... */
  303.         (void) strftime(buf, sizeof(buf) - 1, fmt, tp);
  304.     } else
  305.         (void) strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
  306.     (void) printf("%-*s", v->width, buf);
  307. }
  308.  
  309. lstarted(k, v)
  310.     KINFO *k;
  311.     VAR *v;
  312. {
  313.     char buf[100];
  314.  
  315.     if (!k->ki_u) {
  316.         (void) printf("%-*s", v->width, "-");
  317.         return;
  318.     }
  319.     (void) strftime(buf, sizeof(buf) -1, "%C",
  320.         localtime(&k->ki_u->u_start.tv_sec));
  321.     (void) printf("%-*s", v->width, buf);
  322. }
  323.  
  324. wchan(k, v)
  325.     KINFO *k;
  326.     VAR *v;
  327. {
  328.     if (k->ki_p->p_wchan) {
  329.         if (k->ki_p->p_wmesg)
  330.             (void) printf("%-*.*s", v->width, v->width, k->ki_e->e_wmesg);
  331.         else
  332.             (void) printf("%-*x", v->width,
  333.                 (int)k->ki_p->p_wchan &~ KERNBASE);
  334.     } else
  335.         (void) printf("%-*s", v->width, "-");
  336. }
  337.  
  338. #define pgtok(a)        (((a)*NBPG)/1024)
  339.  
  340. vsize(k, v)
  341.     KINFO *k;
  342.     VAR *v;
  343. {
  344.     (void) printf("%*d", v->width,
  345. #ifndef NEWVM
  346.         pgtok(k->ki_p->p_dsize + k->ki_p->p_ssize + k->ki_e->e_xsize));
  347. #else /* NEWVM */
  348.         pgtok(k->ki_e->e_vm.vm_dsize + k->ki_e->e_vm.vm_ssize +
  349.         k->ki_e->e_vm.vm_tsize));
  350. #endif /* NEWVM */
  351. }
  352.  
  353. rssize(k, v)
  354.     KINFO *k;
  355.     VAR *v;
  356. {
  357. #ifndef NEWVM
  358.     (void) printf("%*d", v->width,
  359.         pgtok(k->ki_p->p_rssize + (k->ki_e->e_xccount ?
  360.         (k->ki_e->e_xrssize / k->ki_e->e_xccount) : 0)));
  361. #else /* NEWVM */
  362.     /* XXX don't have info about shared */
  363.     (void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_rssize));
  364. #endif /* NEWVM */
  365. }
  366.  
  367. p_rssize(k, v)        /* doesn't account for text */
  368.     KINFO *k;
  369.     VAR *v;
  370. {
  371. #ifndef NEWVM
  372.     (void) printf("%*d", v->width, pgtok(k->ki_p->p_rssize));
  373. #else /* NEWVM */
  374.     (void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_rssize));
  375. #endif /* NEWVM */
  376. }
  377.  
  378. cputime(k, v)
  379.     KINFO *k;
  380.     VAR *v;
  381. {
  382.     extern int sumrusage;
  383.     long secs;
  384.     long psecs;    /* "parts" of a second. first micro, then centi */
  385.     char obuff[128];
  386.  
  387.     if (k->ki_p->p_stat == SZOMB || k->ki_u == NULL) {
  388.         secs = 0;
  389.         psecs = 0;
  390.     } else {
  391.         secs = k->ki_p->p_utime.tv_sec +
  392.             k->ki_p->p_stime.tv_sec;
  393.         psecs = k->ki_p->p_utime.tv_usec +
  394.             k->ki_p->p_stime.tv_usec;
  395.         if (sumrusage) {
  396.             secs += k->ki_u->u_cru.ru_utime.tv_sec +
  397.                 k->ki_u->u_cru.ru_stime.tv_sec;
  398.             psecs += k->ki_u->u_cru.ru_utime.tv_usec +
  399.                 k->ki_u->u_cru.ru_stime.tv_usec;
  400.         }
  401.         /*
  402.          * round and scale to 100's
  403.          */
  404.         psecs = (psecs + 5000) / 10000;
  405.         secs += psecs / 100;
  406.         psecs = psecs % 100;
  407.     }
  408.     (void) sprintf(obuff, "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
  409.     (void) printf("%*s", v->width, obuff);
  410. }
  411.  
  412. double
  413. getpcpu(k)
  414.     KINFO *k;
  415. {
  416.     extern fixpt_t ccpu;
  417.     extern int fscale, nlistread, rawcpu;
  418.     struct proc *p;
  419.     static int failure;
  420.  
  421.     if (!nlistread)
  422.         failure = donlist();
  423.     if (failure)
  424.         return (0.0);
  425.  
  426.     p = k->ki_p;
  427. #define    fxtofl(fixpt)    ((double)(fixpt) / fscale)
  428.  
  429.     /* XXX - I don't like this */
  430.     if (p->p_time == 0 || (p->p_flag & SLOAD) == 0)
  431.         return (0.0);
  432.     if (rawcpu)
  433.         return (100.0 * fxtofl(p->p_pctcpu));
  434.     return (100.0 * fxtofl(p->p_pctcpu) /
  435.         (1.0 - exp(p->p_time * log(fxtofl(ccpu)))));
  436. }
  437.  
  438. pcpu(k, v)
  439.     KINFO *k;
  440.     VAR *v;
  441. {
  442.     (void) printf("%*.1f", v->width, getpcpu(k));
  443. }
  444.  
  445. double
  446. getpmem(k)
  447.     KINFO *k;
  448. {
  449.     extern int mempages, nlistread;
  450.     static int failure;
  451.     struct proc *p;
  452.     struct eproc *e;
  453.     double fracmem;
  454.     int szptudot;
  455.  
  456.     if (!nlistread)
  457.         failure = donlist();
  458.     if (failure)
  459.         return (0.0);
  460.  
  461.     p = k->ki_p;
  462.     e = k->ki_e;
  463.     if ((p->p_flag & SLOAD) == 0)
  464.         return (0.0);
  465. #ifndef NEWVM
  466.     szptudot = UPAGES + clrnd(ctopt(p->p_dsize + p->p_ssize + e->e_xsize));
  467.     fracmem = ((float)p->p_rssize + szptudot)/CLSIZE/mempages;
  468.     if (p->p_textp && e->e_xccount)
  469.         fracmem += ((float)e->e_xrssize)/CLSIZE/e->e_xccount/mempages;
  470. #else /* NEWVM */
  471.     /* XXX want pmap ptpages, segtab, etc. (per architecture) */
  472.     szptudot = UPAGES;
  473.     /* XXX don't have info about shared */
  474.     fracmem = ((float)e->e_vm.vm_rssize + szptudot)/CLSIZE/mempages;
  475. #endif /* NEWVM */
  476.     return (100.0 * fracmem);
  477. }
  478.  
  479. pmem(k, v)
  480.     KINFO *k;
  481.     VAR *v;
  482. {
  483.     (void) printf("%*.1f", v->width, getpmem(k));
  484. }
  485.  
  486. pagein(k, v)
  487.     KINFO *k;
  488.     VAR *v;
  489. {
  490.     (void) printf("%*d", v->width, k->ki_u ? k->ki_u->u_ru.ru_majflt : 0);
  491. }
  492.  
  493. maxrss(k, v)
  494.     KINFO *k;
  495.     VAR *v;
  496. {
  497. #ifndef NEWVM    /* not yet */
  498.     if (k->ki_p->p_maxrss != (RLIM_INFINITY/NBPG))
  499.         (void) printf("%*d", v->width, pgtok(k->ki_p->p_maxrss));
  500.     else
  501. #endif /* NEWVM */
  502.         (void) printf("%*s", v->width, "-");
  503. }
  504.  
  505. tsize(k, v)
  506.     KINFO *k;
  507.     VAR *v;
  508. {
  509. #ifndef NEWVM
  510.     (void) printf("%*d", v->width, pgtok(k->ki_e->e_xsize));
  511. #else /* NEWVM */
  512.     (void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_tsize));
  513. #endif /* NEWVM */
  514. }
  515.  
  516. #ifndef NEWVM
  517. trss(k, v)
  518.     KINFO *k;
  519.     VAR *v;
  520. {
  521.     (void) printf("%*d", v->width, pgtok(k->ki_e->e_xrssize));
  522. }
  523. #endif /* NEWVM */
  524.  
  525. /*
  526.  * Generic output routines.  Print fields from various prototype
  527.  * structures.
  528.  */
  529. pvar(k, v)
  530.     KINFO *k;
  531.     VAR *v;
  532. {
  533.     printval((char *)((char *)k->ki_p + v->off), v);
  534. }
  535.  
  536. evar(k, v)
  537.     KINFO *k;
  538.     VAR *v;
  539. {
  540.     printval((char *)((char *)k->ki_e + v->off), v);
  541. }
  542.  
  543. uvar(k, v)
  544.     KINFO *k;
  545.     VAR *v;
  546. {
  547.     if (k->ki_u)
  548.         printval((char *)((char *)k->ki_u + v->off), v);
  549.     else
  550.         (void) printf("%*s", v->width, "-");
  551. }
  552.  
  553. rvar(k, v)
  554.     KINFO *k;
  555.     VAR *v;
  556. {
  557.     if (k->ki_u)
  558.         printval((char *)((char *)(&k->ki_u->u_ru) + v->off), v);
  559.     else
  560.         (void) printf("%*s", v->width, "-");
  561. }
  562.  
  563. printval(bp, v)
  564.     char *bp;
  565.     VAR *v;
  566. {
  567.     static char ofmt[32] = "%";
  568.     register char *cp = ofmt+1, *fcp = v->fmt;
  569.  
  570.     if (v->flag & LJUST)
  571.         *cp++ = '-';
  572.     *cp++ = '*';
  573.     while (*cp++ = *fcp++);
  574.  
  575.     switch (v->type) {
  576.     case CHAR:
  577.         (void) printf(ofmt, v->width, *(char *)bp);
  578.         break;
  579.     case UCHAR:
  580.         (void) printf(ofmt, v->width, *(u_char *)bp);
  581.         break;
  582.     case SHORT:
  583.         (void) printf(ofmt, v->width, *(short *)bp);
  584.         break;
  585.     case USHORT:
  586.         (void) printf(ofmt, v->width, *(u_short *)bp);
  587.         break;
  588.     case LONG:
  589.         (void) printf(ofmt, v->width, *(long *)bp);
  590.         break;
  591.     case ULONG:
  592.         (void) printf(ofmt, v->width, *(u_long *)bp);
  593.         break;
  594.     case KPTR:
  595.         (void) printf(ofmt, v->width, *(u_long *)bp &~ KERNBASE);
  596.         break;
  597.     default:
  598.         err("unknown type %d", v->type);
  599.     }
  600. }
  601.