summaryrefslogtreecommitdiff
path: root/bin/ps/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/ps/print.c')
-rw-r--r--bin/ps/print.c1413
1 files changed, 0 insertions, 1413 deletions
diff --git a/bin/ps/print.c b/bin/ps/print.c
deleted file mode 100644
index e725ef0..0000000
--- a/bin/ps/print.c
+++ /dev/null
@@ -1,1413 +0,0 @@
-/* $NetBSD: print.c,v 1.130 2018/09/19 15:20:39 maxv Exp $ */
-
-/*
- * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Simon Burge.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94";
-#else
-__RCSID("$NetBSD: print.c,v 1.130 2018/09/19 15:20:39 maxv Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/lwp.h>
-#include <sys/proc.h>
-#include <sys/stat.h>
-#include <sys/ucred.h>
-#include <sys/sysctl.h>
-
-#include <err.h>
-#include <grp.h>
-#include <kvm.h>
-#include <math.h>
-#include <nlist.h>
-#include <pwd.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <tzfile.h>
-#include <unistd.h>
-
-#include "ps.h"
-
-static char *cmdpart(char *);
-static void printval(void *, VAR *, enum mode);
-static int titlecmp(char *, char **);
-
-static void doubleprintorsetwidth(VAR *, double, int, enum mode);
-static void intprintorsetwidth(VAR *, int, enum mode);
-static void strprintorsetwidth(VAR *, const char *, enum mode);
-
-static time_t now;
-
-#define min(a,b) ((a) <= (b) ? (a) : (b))
-
-static int
-iwidth(u_int64_t v)
-{
- u_int64_t nlim, lim;
- int w = 1;
-
- for (lim = 10; v >= lim; lim = nlim) {
- nlim = lim * 10;
- w++;
- if (nlim < lim)
- break;
- }
- return w;
-}
-
-static char *
-cmdpart(char *arg0)
-{
- char *cp;
-
- return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);
-}
-
-void
-printheader(void)
-{
- int len;
- VAR *v;
- struct varent *vent;
- static int firsttime = 1;
- static int noheader = 0;
-
- /*
- * If all the columns have user-specified null headers,
- * don't print the blank header line at all.
- */
- if (firsttime) {
- SIMPLEQ_FOREACH(vent, &displaylist, next) {
- if (vent->var->header[0])
- break;
- }
- if (vent == NULL) {
- noheader = 1;
- firsttime = 0;
- }
-
- }
- if (noheader)
- return;
-
- SIMPLEQ_FOREACH(vent, &displaylist, next) {
- v = vent->var;
- if (firsttime) {
- len = strlen(v->header);
- if (len > v->width)
- v->width = len;
- totwidth += v->width + 1; /* +1 for space */
- }
- if (v->flag & LJUST) {
- if (SIMPLEQ_NEXT(vent, next) == NULL) /* last one */
- (void)printf("%s", v->header);
- else
- (void)printf("%-*s", v->width,
- v->header);
- } else
- (void)printf("%*s", v->width, v->header);
- if (SIMPLEQ_NEXT(vent, next) != NULL)
- (void)putchar(' ');
- }
- (void)putchar('\n');
- if (firsttime) {
- firsttime = 0;
- totwidth--; /* take off last space */
- }
-}
-
-/*
- * Return 1 if the command name in the argument vector (u-area) does
- * not match the command name (p_comm)
- */
-static int
-titlecmp(char *name, char **argv)
-{
- char *title;
- int namelen;
-
-
- /* no argument vector == no match; system processes/threads do that */
- if (argv == 0 || argv[0] == 0)
- return (1);
-
- title = cmdpart(argv[0]);
-
- /* the basename matches */
- if (!strcmp(name, title))
- return (0);
-
- /* handle login shells, by skipping the leading - */
- if (title[0] == '-' && !strcmp(name, title + 1))
- return (0);
-
- namelen = strlen(name);
-
- /* handle daemons that report activity as daemonname: activity */
- if (argv[1] == 0 &&
- !strncmp(name, title, namelen) &&
- title[namelen + 0] == ':' &&
- title[namelen + 1] == ' ')
- return (0);
-
- return (1);
-}
-
-static void
-doubleprintorsetwidth(VAR *v, double val, int prec, enum mode mode)
-{
- int fmtlen;
-
- if (mode == WIDTHMODE) {
- if (val < 0.0 && val < v->longestnd) {
- fmtlen = (int)log10(-val) + prec + 2;
- v->longestnd = val;
- if (fmtlen > v->width)
- v->width = fmtlen;
- } else if (val > 0.0 && val > v->longestpd) {
- fmtlen = (int)log10(val) + prec + 1;
- v->longestpd = val;
- if (fmtlen > v->width)
- v->width = fmtlen;
- }
- } else {
- (void)printf("%*.*f", v->width, prec, val);
- }
-}
-
-static void
-intprintorsetwidth(VAR *v, int val, enum mode mode)
-{
- int fmtlen;
-
- if (mode == WIDTHMODE) {
- if (val < 0 && val < v->longestn) {
- v->longestn = val;
- fmtlen = iwidth(-val) + 1;
- if (fmtlen > v->width)
- v->width = fmtlen;
- } else if (val > 0 && val > v->longestp) {
- v->longestp = val;
- fmtlen = iwidth(val);
- if (fmtlen > v->width)
- v->width = fmtlen;
- }
- } else
- (void)printf("%*d", v->width, val);
-}
-
-static void
-strprintorsetwidth(VAR *v, const char *str, enum mode mode)
-{
- int len;
-
- if (mode == WIDTHMODE) {
- len = strlen(str);
- if (len > v->width)
- v->width = len;
- } else {
- if (v->flag & LJUST)
- (void)printf("%-*.*s", v->width, v->width, str);
- else
- (void)printf("%*.*s", v->width, v->width, str);
- }
-}
-
-void
-command(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *ki = pi->ki;
- VAR *v;
- int left;
- char **argv, **p, *name;
-
- if (mode == WIDTHMODE)
- return;
-
- v = ve->var;
- if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
- if (SIMPLEQ_NEXT(ve, next) == NULL) {
- left = termwidth - (totwidth - v->width);
- if (left < 1) /* already wrapped, just use std width */
- left = v->width;
- } else
- left = v->width;
- } else
- left = -1;
- if (needenv && kd) {
- argv = kvm_getenvv2(kd, ki, termwidth);
- if ((p = argv) != NULL) {
- while (*p) {
- fmt_puts(*p, &left);
- p++;
- fmt_putc(' ', &left);
- }
- }
- }
- if (needcomm) {
- if (pi->prefix)
- (void)fmt_puts(pi->prefix, &left);
- name = ki->p_comm;
- if (!commandonly) {
- argv = kvm_getargv2(kd, ki, termwidth);
- if ((p = argv) != NULL) {
- while (*p) {
- fmt_puts(*p, &left);
- p++;
- fmt_putc(' ', &left);
- if (v->flag & ARGV0)
- break;
- }
- if (!(v->flag & ARGV0) &&
- titlecmp(name, argv)) {
- /*
- * append the real command name within
- * parentheses, if the command name
- * does not match the one in the
- * argument vector
- */
- fmt_putc('(', &left);
- fmt_puts(name, &left);
- fmt_putc(')', &left);
- }
- } else {
- /*
- * Commands that don't set an argv vector
- * are printed with square brackets if they
- * are system commands. Otherwise they are
- * printed within parentheses.
- */
- if (ki->p_flag & P_SYSTEM) {
- fmt_putc('[', &left);
- fmt_puts(name, &left);
- fmt_putc(']', &left);
- } else {
- fmt_putc('(', &left);
- fmt_puts(name, &left);
- fmt_putc(')', &left);
- }
- }
- } else {
- fmt_puts(name, &left);
- }
- }
- if (SIMPLEQ_NEXT(ve, next) != NULL && left > 0)
- (void)printf("%*s", left, "");
-}
-
-void
-groups(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *ki = pi->ki;
- VAR *v;
- int left, i;
- char buf[16], *p;
-
- if (mode == WIDTHMODE)
- return;
-
- v = ve->var;
- if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
- if (SIMPLEQ_NEXT(ve, next) == NULL) {
- left = termwidth - (totwidth - v->width);
- if (left < 1) /* already wrapped, just use std width */
- left = v->width;
- } else
- left = v->width;
- } else
- left = -1;
-
- if (ki->p_ngroups == 0)
- fmt_putc('-', &left);
-
- for (i = 0; i < ki->p_ngroups; i++) {
- (void)snprintf(buf, sizeof(buf), "%d", ki->p_groups[i]);
- if (i)
- fmt_putc(' ', &left);
- for (p = &buf[0]; *p; p++)
- fmt_putc(*p, &left);
- }
-
- if (SIMPLEQ_NEXT(ve, next) != NULL && left > 0)
- (void)printf("%*s", left, "");
-}
-
-void
-groupnames(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *ki = pi->ki;
- VAR *v;
- int left, i;
- const char *p;
-
- if (mode == WIDTHMODE)
- return;
-
- v = ve->var;
- if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
- if (SIMPLEQ_NEXT(ve, next) == NULL) {
- left = termwidth - (totwidth - v->width);
- if (left < 1) /* already wrapped, just use std width */
- left = v->width;
- } else
- left = v->width;
- } else
- left = -1;
-
- if (ki->p_ngroups == 0)
- fmt_putc('-', &left);
-
- for (i = 0; i < ki->p_ngroups; i++) {
- if (i)
- fmt_putc(' ', &left);
- for (p = group_from_gid(ki->p_groups[i], 0); *p; p++)
- fmt_putc(*p, &left);
- }
-
- if (SIMPLEQ_NEXT(ve, next) != NULL && left > 0)
- (void)printf("%*s", left, "");
-}
-
-void
-ucomm(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- char buf[MAXPATHLEN], *p;
- VAR *v;
-
- v = ve->var;
- if (pi->prefix)
- snprintf(p = buf, sizeof(buf), "%s%s", pi->prefix, k->p_comm);
- else
- p = k->p_comm;
- strprintorsetwidth(v, p, mode);
-}
-
-void
-emul(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- strprintorsetwidth(v, k->p_ename, mode);
-}
-
-void
-logname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- strprintorsetwidth(v, k->p_login, mode);
-}
-
-void
-state(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- int flag, is_zombie;
- char *cp;
- VAR *v;
- char buf[16];
-
- is_zombie = 0;
- v = ve->var;
- flag = k->p_flag;
- cp = buf;
-
- /*
- * NOTE: There are historical letters, which are no longer used:
- *
- * - W: indicated that process is swapped out.
- * - L: indicated non-zero l_holdcnt (i.e. that process was
- * prevented from swapping-out.
- *
- * These letters should not be used for new states to avoid
- * conflicts with old applications which might depend on them.
- */
- switch (k->p_stat) {
-
- case LSSTOP:
- *cp = 'T';
- break;
-
- case LSSLEEP:
- if (flag & L_SINTR) /* interruptable (long) */
- *cp = (int)k->p_slptime >= maxslp ? 'I' : 'S';
- else
- *cp = 'D';
- break;
-
- case LSRUN:
- case LSIDL:
- *cp = 'R';
- break;
-
- case LSONPROC:
- *cp = 'O';
- break;
-
- case LSZOMB:
- *cp = 'Z';
- is_zombie = 1;
- break;
-
- case LSSUSPENDED:
- *cp = 'U';
- break;
-
- default:
- *cp = '?';
- }
- cp++;
- if (k->p_nice < NZERO)
- *cp++ = '<';
- else if (k->p_nice > NZERO)
- *cp++ = 'N';
- if (flag & P_TRACED)
- *cp++ = 'X';
- if (flag & P_WEXIT && !is_zombie)
- *cp++ = 'E';
- if (flag & P_PPWAIT)
- *cp++ = 'V';
- if (flag & P_SYSTEM)
- *cp++ = 'K';
- if (k->p_eflag & EPROC_SLEADER)
- *cp++ = 's';
- if (flag & P_SA)
- *cp++ = 'a';
- else if (k->p_nlwps > 1)
- *cp++ = 'l';
- if ((flag & P_CONTROLT) && k->p__pgid == k->p_tpgid)
- *cp++ = '+';
- *cp = '\0';
- strprintorsetwidth(v, buf, mode);
-}
-
-void
-lstate(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_lwp *k = pi->li;
- int flag;
- char *cp;
- VAR *v;
- char buf[16];
-
- v = ve->var;
- flag = k->l_flag;
- cp = buf;
-
- switch (k->l_stat) {
-
- case LSSTOP:
- *cp = 'T';
- break;
-
- case LSSLEEP:
- if (flag & L_SINTR) /* interruptible (long) */
- *cp = (int)k->l_slptime >= maxslp ? 'I' : 'S';
- else
- *cp = 'D';
- break;
-
- case LSRUN:
- case LSIDL:
- *cp = 'R';
- break;
-
- case LSONPROC:
- *cp = 'O';
- break;
-
- case LSZOMB:
- case LSDEAD:
- *cp = 'Z';
- break;
-
- case LSSUSPENDED:
- *cp = 'U';
- break;
-
- default:
- *cp = '?';
- }
- cp++;
- if (flag & L_SYSTEM)
- *cp++ = 'K';
- if (flag & L_SA)
- *cp++ = 'a';
- if (flag & L_DETACHED)
- *cp++ = '-';
- *cp = '\0';
- strprintorsetwidth(v, buf, mode);
-}
-
-void
-pnice(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- intprintorsetwidth(v, k->p_nice - NZERO, mode);
-}
-
-void
-pri(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_lwp *l = pi->li;
- VAR *v;
-
- v = ve->var;
- intprintorsetwidth(v, l->l_priority, mode);
-}
-
-void
-usrname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- strprintorsetwidth(v, user_from_uid(k->p_uid, 0), mode);
-}
-
-void
-runame(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- strprintorsetwidth(v, user_from_uid(k->p_ruid, 0), mode);
-}
-
-void
-svuname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- strprintorsetwidth(v, user_from_uid(k->p_svuid, 0), mode);
-}
-
-void
-gname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- strprintorsetwidth(v, group_from_gid(k->p_gid, 0), mode);
-}
-
-void
-rgname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- strprintorsetwidth(v, group_from_gid(k->p_rgid, 0), mode);
-}
-
-void
-svgname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- strprintorsetwidth(v, group_from_gid(k->p_svgid, 0), mode);
-}
-
-void
-tdev(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
- dev_t dev;
- char buff[16];
-
- v = ve->var;
- dev = k->p_tdev;
- if (dev == NODEV) {
- if (mode == PRINTMODE)
- (void)printf("%*s", v->width, "?");
- else
- if (v->width < 2)
- v->width = 2;
- } else {
- (void)snprintf(buff, sizeof(buff),
- "%lld/%lld", (long long)major(dev), (long long)minor(dev));
- strprintorsetwidth(v, buff, mode);
- }
-}
-
-void
-tname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
- dev_t dev;
- const char *ttname;
- int noctty;
-
- v = ve->var;
- dev = k->p_tdev;
- if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) {
- if (mode == PRINTMODE)
- (void)printf("%-*s", v->width, "?");
- else
- if (v->width < 2)
- v->width = 2;
- } else {
- noctty = !(k->p_eflag & EPROC_CTTY) ? 1 : 0;
- if (mode == WIDTHMODE) {
- int fmtlen;
-
- fmtlen = strlen(ttname) + noctty;
- if (v->width < fmtlen)
- v->width = fmtlen;
- } else {
- if (noctty)
- (void)printf("%-*s-", v->width - 1, ttname);
- else
- (void)printf("%-*s", v->width, ttname);
- }
- }
-}
-
-void
-longtname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
- dev_t dev;
- const char *ttname;
-
- v = ve->var;
- dev = k->p_tdev;
- if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) {
- if (mode == PRINTMODE)
- (void)printf("%-*s", v->width, "?");
- else
- if (v->width < 2)
- v->width = 2;
- } else {
- strprintorsetwidth(v, ttname, mode);
- }
-}
-
-void
-started(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
- time_t startt;
- struct tm *tp;
- char buf[100], *cp;
-
- v = ve->var;
- if (!k->p_uvalid) {
- if (mode == PRINTMODE)
- (void)printf("%*s", v->width, "-");
- return;
- }
-
- startt = k->p_ustart_sec;
- tp = localtime(&startt);
- if (now == 0)
- (void)time(&now);
- if (now - k->p_ustart_sec < SECSPERDAY)
- /* I *hate* SCCS... */
- (void)strftime(buf, sizeof(buf) - 1, "%l:%" "M%p", tp);
- else if (now - k->p_ustart_sec < DAYSPERWEEK * SECSPERDAY)
- /* I *hate* SCCS... */
- (void)strftime(buf, sizeof(buf) - 1, "%a%" "I%p", tp);
- else
- (void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
- /* %e and %l can start with a space. */
- cp = buf;
- if (*cp == ' ')
- cp++;
- strprintorsetwidth(v, cp, mode);
-}
-
-void
-lstarted(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
- time_t startt;
- char buf[100];
-
- v = ve->var;
- if (!k->p_uvalid) {
- /*
- * Minimum width is less than header - we don't
- * need to check it every time.
- */
- if (mode == PRINTMODE)
- (void)printf("%*s", v->width, "-");
- return;
- }
- startt = k->p_ustart_sec;
-
- /* assume all times are the same length */
- if (mode != WIDTHMODE || v->width == 0) {
- (void)strftime(buf, sizeof(buf) -1, "%c",
- localtime(&startt));
- strprintorsetwidth(v, buf, mode);
- }
-}
-
-void
-elapsed(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
- int32_t origseconds, secs, mins, hours, days;
- int fmtlen, printed_something;
-
- v = ve->var;
- if (k->p_uvalid == 0) {
- origseconds = 0;
- } else {
- if (now == 0)
- (void)time(&now);
- origseconds = now - k->p_ustart_sec;
- if (origseconds < 0) {
- /*
- * Don't try to be fancy if the machine's
- * clock has been rewound to before the
- * process "started".
- */
- origseconds = 0;
- }
- }
-
- secs = origseconds;
- mins = secs / SECSPERMIN;
- secs %= SECSPERMIN;
- hours = mins / MINSPERHOUR;
- mins %= MINSPERHOUR;
- days = hours / HOURSPERDAY;
- hours %= HOURSPERDAY;
-
- if (mode == WIDTHMODE) {
- if (origseconds == 0)
- /* non-zero so fmtlen is calculated at least once */
- origseconds = 1;
-
- if (origseconds > v->longestp) {
- v->longestp = origseconds;
-
- if (days > 0) {
- /* +9 for "-hh:mm:ss" */
- fmtlen = iwidth(days) + 9;
- } else if (hours > 0) {
- /* +6 for "mm:ss" */
- fmtlen = iwidth(hours) + 6;
- } else {
- /* +3 for ":ss" */
- fmtlen = iwidth(mins) + 3;
- }
-
- if (fmtlen > v->width)
- v->width = fmtlen;
- }
- } else {
- printed_something = 0;
- fmtlen = v->width;
-
- if (days > 0) {
- (void)printf("%*d", fmtlen - 9, days);
- printed_something = 1;
- } else if (fmtlen > 9) {
- (void)printf("%*s", fmtlen - 9, "");
- }
- if (fmtlen > 9)
- fmtlen = 9;
-
- if (printed_something) {
- (void)printf("-%.*d", fmtlen - 7, hours);
- printed_something = 1;
- } else if (hours > 0) {
- (void)printf("%*d", fmtlen - 6, hours);
- printed_something = 1;
- } else if (fmtlen > 6) {
- (void)printf("%*s", fmtlen - 6, "");
- }
- if (fmtlen > 6)
- fmtlen = 6;
-
- /* Don't need to set fmtlen or printed_something any more... */
- if (printed_something) {
- (void)printf(":%.*d", fmtlen - 4, mins);
- } else if (mins > 0) {
- (void)printf("%*d", fmtlen - 3, mins);
- } else if (fmtlen > 3) {
- (void)printf("%*s", fmtlen - 3, "0");
- }
-
- (void)printf(":%.2d", secs);
- }
-}
-
-void
-wchan(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_lwp *l = pi->li;
- VAR *v;
-
- v = ve->var;
- if (l->l_wmesg[0]) {
- strprintorsetwidth(v, l->l_wmesg, mode);
- v->width = min(v->width, KI_WMESGLEN);
- } else {
- if (mode == PRINTMODE)
- (void)printf("%-*s", v->width, "-");
- }
-}
-
-#define pgtok(a) (((a)*(size_t)getpagesize())/1024)
-
-void
-vsize(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- intprintorsetwidth(v, pgtok(k->p_vm_msize), mode);
-}
-
-void
-rssize(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- /* XXX don't have info about shared */
- intprintorsetwidth(v, pgtok(k->p_vm_rssize), mode);
-}
-
-void
-p_rssize(struct pinfo *pi, VARENT *ve, enum mode mode) /* doesn't account for text */
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- intprintorsetwidth(v, pgtok(k->p_vm_rssize), mode);
-}
-
-void
-cpuid(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_lwp *l = pi->li;
- VAR *v;
-
- v = ve->var;
- intprintorsetwidth(v, l->l_cpuid, mode);
-}
-
-static void
-cputime1(int32_t secs, int32_t psecs, VAR *v, enum mode mode)
-{
- int fmtlen;
-
- /*
- * round and scale to 100's
- */
- psecs = (psecs + 5000) / 10000;
- secs += psecs / 100;
- psecs = psecs % 100;
-
- if (mode == WIDTHMODE) {
- /*
- * Ugg, this is the only field where a value of 0 is longer
- * than the column title.
- * Use SECSPERMIN, because secs is divided by that when
- * passed to iwidth().
- */
- if (secs == 0)
- secs = SECSPERMIN;
-
- if (secs > v->longestp) {
- v->longestp = secs;
- /* "+6" for the ":%02ld.%02ld" in the printf() below */
- fmtlen = iwidth(secs / SECSPERMIN) + 6;
- if (fmtlen > v->width)
- v->width = fmtlen;
- }
- } else {
- (void)printf("%*ld:%02ld.%02ld", v->width - 6,
- (long)(secs / SECSPERMIN), (long)(secs % SECSPERMIN),
- (long)psecs);
- }
-}
-
-void
-cputime(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
- int32_t secs;
- int32_t psecs; /* "parts" of a second. first micro, then centi */
-
- v = ve->var;
-
- /*
- * This counts time spent handling interrupts. We could
- * fix this, but it is not 100% trivial (and interrupt
- * time fractions only work on the sparc anyway). XXX
- */
- secs = k->p_rtime_sec;
- psecs = k->p_rtime_usec;
- if (sumrusage) {
- secs += k->p_uctime_sec;
- psecs += k->p_uctime_usec;
- }
-
- cputime1(secs, psecs, v, mode);
-}
-
-void
-lcputime(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_lwp *l = pi->li;
- VAR *v;
- int32_t secs;
- int32_t psecs; /* "parts" of a second. first micro, then centi */
-
- v = ve->var;
-
- secs = l->l_rtime_sec;
- psecs = l->l_rtime_usec;
-
- cputime1(secs, psecs, v, mode);
-}
-
-void
-pcpu(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- VAR *v;
- double dbl;
-
- v = ve->var;
- dbl = pi->pcpu;
- doubleprintorsetwidth(v, dbl, (dbl >= 99.95) ? 0 : 1, mode);
-}
-
-double
-getpmem(const struct kinfo_proc2 *k)
-{
- double fracmem;
- int szptudot;
-
- if (!nlistread)
- donlist();
-
- /* XXX want pmap ptpages, segtab, etc. (per architecture) */
- szptudot = uspace/getpagesize();
- /* XXX don't have info about shared */
- fracmem = ((float)k->p_vm_rssize + szptudot)/mempages;
- return (100.0 * fracmem);
-}
-
-void
-pmem(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- doubleprintorsetwidth(v, getpmem(k), 1, mode);
-}
-
-void
-pagein(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- intprintorsetwidth(v, k->p_uvalid ? k->p_uru_majflt : 0, mode);
-}
-
-void
-maxrss(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- VAR *v;
-
- v = ve->var;
- /* No need to check width! */
- if (mode == PRINTMODE)
- (void)printf("%*s", v->width, "-");
-}
-
-void
-tsize(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_proc2 *k = pi->ki;
- VAR *v;
-
- v = ve->var;
- intprintorsetwidth(v, pgtok(k->p_vm_tsize), mode);
-}
-
-/*
- * Generic output routines. Print fields from various prototype
- * structures.
- */
-static void
-printval(void *bp, VAR *v, enum mode mode)
-{
- static char ofmt[32] = "%";
- int width, vok, fmtlen;
- const char *fcp;
- char *cp;
- int64_t val;
- u_int64_t uval;
-
- val = 0; /* XXXGCC -Wuninitialized [hpcarm] */
- uval = 0; /* XXXGCC -Wuninitialized [hpcarm] */
-
- /*
- * Note that the "INF127" check is nonsensical for types
- * that are or can be signed.
- */
-#define GET(type) (*(type *)bp)
-#define CHK_INF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n))
-
-#define VSIGN 1
-#define VUNSIGN 2
-#define VPTR 3
-
- if (mode == WIDTHMODE) {
- vok = 0;
- switch (v->type) {
- case CHAR:
- val = GET(char);
- vok = VSIGN;
- break;
- case UCHAR:
- uval = CHK_INF127(GET(u_char));
- vok = VUNSIGN;
- break;
- case SHORT:
- val = GET(short);
- vok = VSIGN;
- break;
- case USHORT:
- uval = CHK_INF127(GET(u_short));
- vok = VUNSIGN;
- break;
- case INT32:
- val = GET(int32_t);
- vok = VSIGN;
- break;
- case INT:
- val = GET(int);
- vok = VSIGN;
- break;
- case UINT:
- case UINT32:
- uval = CHK_INF127(GET(u_int));
- vok = VUNSIGN;
- break;
- case LONG:
- val = GET(long);
- vok = VSIGN;
- break;
- case ULONG:
- uval = CHK_INF127(GET(u_long));
- vok = VUNSIGN;
- break;
- case KPTR:
- uval = GET(u_int64_t);
- vok = VPTR;
- break;
- case KPTR24:
- uval = GET(u_int64_t);
- uval &= 0xffffff;
- vok = VPTR;
- break;
- case INT64:
- val = GET(int64_t);
- vok = VSIGN;
- break;
- case UINT64:
- uval = CHK_INF127(GET(u_int64_t));
- vok = VUNSIGN;
- break;
-
- case SIGLIST:
- default:
- /* nothing... */;
- }
- switch (vok) {
- case VSIGN:
- if (val < 0 && val < v->longestn) {
- v->longestn = val;
- fmtlen = iwidth(-val) + 1;
- if (fmtlen > v->width)
- v->width = fmtlen;
- } else if (val > 0 && val > v->longestp) {
- v->longestp = val;
- fmtlen = iwidth(val);
- if (fmtlen > v->width)
- v->width = fmtlen;
- }
- return;
- case VUNSIGN:
- if (uval > v->longestu) {
- v->longestu = uval;
- v->width = iwidth(uval);
- }
- return;
- case VPTR:
- fmtlen = 0;
- while (uval > 0) {
- uval >>= 4;
- fmtlen++;
- }
- if (fmtlen > v->width)
- v->width = fmtlen;
- return;
- }
- }
-
- width = v->width;
- cp = ofmt + 1;
- fcp = v->fmt;
- if (v->flag & LJUST)
- *cp++ = '-';
- *cp++ = '*';
- while ((*cp++ = *fcp++) != '\0')
- continue;
-
- switch (v->type) {
- case CHAR:
- (void)printf(ofmt, width, GET(char));
- return;
- case UCHAR:
- (void)printf(ofmt, width, CHK_INF127(GET(u_char)));
- return;
- case SHORT:
- (void)printf(ofmt, width, GET(short));
- return;
- case USHORT:
- (void)printf(ofmt, width, CHK_INF127(GET(u_short)));
- return;
- case INT:
- (void)printf(ofmt, width, GET(int));
- return;
- case UINT:
- (void)printf(ofmt, width, CHK_INF127(GET(u_int)));
- return;
- case LONG:
- (void)printf(ofmt, width, GET(long));
- return;
- case ULONG:
- (void)printf(ofmt, width, CHK_INF127(GET(u_long)));
- return;
- case KPTR:
- (void)printf(ofmt, width, GET(u_int64_t));
- return;
- case KPTR24:
- (void)printf(ofmt, width, GET(u_int64_t) & 0xffffff);
- return;
- case INT32:
- (void)printf(ofmt, width, GET(int32_t));
- return;
- case UINT32:
- (void)printf(ofmt, width, CHK_INF127(GET(u_int32_t)));
- return;
- case SIGLIST:
- {
- sigset_t *s = (sigset_t *)(void *)bp;
- size_t i;
-#define SIGSETSIZE (sizeof(s->__bits) / sizeof(s->__bits[0]))
- char buf[SIGSETSIZE * 8 + 1];
-
- for (i = 0; i < SIGSETSIZE; i++)
- (void)snprintf(&buf[i * 8], 9, "%.8x",
- s->__bits[(SIGSETSIZE - 1) - i]);
-
- /* Skip leading zeroes */
- for (i = 0; buf[i] == '0'; i++)
- continue;
-
- if (buf[i] == '\0')
- i--;
- strprintorsetwidth(v, buf + i, mode);
-#undef SIGSETSIZE
- }
- return;
- case INT64:
- (void)printf(ofmt, width, GET(int64_t));
- return;
- case UINT64:
- (void)printf(ofmt, width, CHK_INF127(GET(u_int64_t)));
- return;
- default:
- errx(EXIT_FAILURE, "unknown type %d", v->type);
- }
-#undef GET
-#undef CHK_INF127
-}
-
-void
-pvar(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- VAR *v = ve->var;
- char *b = (v->flag & LWP) ? (char *)pi->li : (char *)pi->ki;
-
- if ((v->flag & UAREA) && !pi->ki->p_uvalid) {
- if (mode == PRINTMODE)
- (void)printf("%*s", v->width, "-");
- return;
- }
-
- (void)printval(b + v->off, v, mode);
-}
-
-void
-putimeval(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- VAR *v = ve->var;
- struct kinfo_proc2 *k = pi->ki;
- char *b = (v->flag & LWP) ? (char *)pi->li : (char *)pi->ki;
- ulong secs = *(uint32_t *)(b + v->off);
- ulong usec = *(uint32_t *)(b + v->off + sizeof (uint32_t));
- int fmtlen;
-
- if (!k->p_uvalid) {
- if (mode == PRINTMODE)
- (void)printf("%*s", v->width, "-");
- return;
- }
-
- if (mode == WIDTHMODE) {
- if (secs == 0)
- /* non-zero so fmtlen is calculated at least once */
- secs = 1;
- if (secs > v->longestu) {
- v->longestu = secs;
- if (secs <= 999)
- /* sss.ssssss */
- fmtlen = iwidth(secs) + 6 + 1;
- else
- /* hh:mm:ss.ss */
- fmtlen = iwidth((secs + 1) / SECSPERHOUR)
- + 2 + 1 + 2 + 1 + 2 + 1;
- if (fmtlen > v->width)
- v->width = fmtlen;
- }
- return;
- }
-
- if (secs < 999)
- (void)printf( "%*lu.%.6lu", v->width - 6 - 1, secs, usec);
- else {
- uint h, m;
- usec += 5000;
- if (usec >= 1000000) {
- usec -= 1000000;
- secs++;
- }
- m = secs / SECSPERMIN;
- secs -= m * SECSPERMIN;
- h = m / MINSPERHOUR;
- m -= h * MINSPERHOUR;
- (void)printf( "%*u:%.2u:%.2lu.%.2lu", v->width - 9, h, m, secs,
- usec / 10000u );
- }
-}
-
-void
-lname(struct pinfo *pi, VARENT *ve, enum mode mode)
-{
- struct kinfo_lwp *l = pi->li;
- VAR *v;
-
- v = ve->var;
- if (l->l_name[0] != '\0') {
- strprintorsetwidth(v, l->l_name, mode);
- v->width = min(v->width, KI_LNAMELEN);
- } else {
- if (mode == PRINTMODE)
- (void)printf("%-*s", v->width, "-");
- }
-}