Index: head/bin/ps/extern.h =================================================================== --- head/bin/ps/extern.h (revision 130973) +++ head/bin/ps/extern.h (revision 130974) @@ -1,87 +1,88 @@ /*- * Copyright (c) 1991, 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. * 4. 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. * * @(#)extern.h 8.3 (Berkeley) 4/2/94 * $FreeBSD$ */ struct kinfo; struct nlist; struct var; struct varent; extern fixpt_t ccpu; extern int cflag, eval, fscale, nlistread, rawcpu; extern unsigned long mempages; extern time_t now; extern int sumrusage, termwidth, totwidth; extern VARENT *vhead; __BEGIN_DECLS void arguments(KINFO *, VARENT *); void command(KINFO *, VARENT *); void cputime(KINFO *, VARENT *); int donlist(void); void elapsed(KINFO *, VARENT *); void emulname(KINFO *, VARENT *); VARENT *find_varentry(VAR *); const char *fmt_argv(char **, char *, size_t); double getpcpu(const KINFO *); void kvar(KINFO *, VARENT *); void label(KINFO *, VARENT *); void logname(KINFO *, VARENT *); void longtname(KINFO *, VARENT *); void lstarted(KINFO *, VARENT *); void maxrss(KINFO *, VARENT *); void lockname(KINFO *, VARENT *); void mwchan(KINFO *, VARENT *); void nwchan(KINFO *, VARENT *); void pagein(KINFO *, VARENT *); void parsefmt(const char *, int); void pcpu(KINFO *, VARENT *); void pmem(KINFO *, VARENT *); void pri(KINFO *, VARENT *); void printheader(void); void priorityr(KINFO *, VARENT *); void rgroupname(KINFO *, VARENT *); void runame(KINFO *, VARENT *); void rvar(KINFO *, VARENT *); int s_label(KINFO *); int s_rgroupname(KINFO *); int s_runame(KINFO *); int s_uname(KINFO *); void showkey(void); void started(KINFO *, VARENT *); void state(KINFO *, VARENT *); void tdev(KINFO *, VARENT *); void tname(KINFO *, VARENT *); void ucomm(KINFO *, VARENT *); void uname(KINFO *, VARENT *); +void upr(KINFO *, VARENT *); void vsize(KINFO *, VARENT *); void wchan(KINFO *, VARENT *); __END_DECLS Index: head/bin/ps/keyword.c =================================================================== --- head/bin/ps/keyword.c (revision 130973) +++ head/bin/ps/keyword.c (revision 130974) @@ -1,336 +1,335 @@ /*- * 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. * 4. 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. */ #if 0 #ifndef lint static char sccsid[] = "@(#)keyword.c 8.5 (Berkeley) 4/2/94"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include "ps.h" static VAR *findvar(char *, int, char **header); static int vcmp(const void *, const void *); /* Compute offset in common structures. */ #define KOFF(x) offsetof(struct kinfo_proc, x) #define ROFF(x) offsetof(struct rusage, x) #define EMULLEN 13 /* enough for "FreeBSD ELF32" */ #define LWPFMT "d" #define LWPLEN 6 #define NLWPFMT "d" #define NLWPLEN 4 #define UIDFMT "u" #define UIDLEN 5 #define PIDFMT "d" #define PIDLEN 5 #define USERLEN (MAXLOGNAME - 1) /* PLEASE KEEP THE TABLE BELOW SORTED ALPHABETICALLY!!! */ static VAR var[] = { {"%cpu", "%CPU", NULL, 0, pcpu, NULL, 4, 0, CHAR, NULL, 0}, {"%mem", "%MEM", NULL, 0, pmem, NULL, 4, 0, CHAR, NULL, 0}, {"acflag", "ACFLG", NULL, 0, kvar, NULL, 3, KOFF(ki_acflag), USHORT, "x", 0}, {"acflg", "", "acflag", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"args", "COMMAND", NULL, COMM|LJUST|USER, arguments, NULL, 16, 0, CHAR, NULL, 0}, {"blocked", "", "sigmask", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"caught", "", "sigcatch", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"comm", "COMMAND", NULL, LJUST, ucomm, NULL, MAXCOMLEN, 0, CHAR, NULL, 0}, {"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16, 0, CHAR, NULL, 0}, {"cpu", "CPU", NULL, 0, kvar, NULL, 3, KOFF(ki_estcpu), UINT, "d", 0}, {"cputime", "", "time", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"emul", "EMUL", NULL, LJUST, emulname, NULL, EMULLEN, 0, CHAR, NULL, 0}, {"etime", "ELAPSED", NULL, USER, elapsed, NULL, 12, 0, CHAR, NULL, 0}, {"f", "F", NULL, 0, kvar, NULL, 7, KOFF(ki_flag), INT, "x", 0}, {"flags", "", "f", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"ignored", "", "sigignore", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"inblk", "INBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_inblock), LONG, "ld", 0}, {"inblock", "", "inblk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"jobc", "JOBC", NULL, 0, kvar, NULL, 4, KOFF(ki_jobc), SHORT, "d", 0}, {"ktrace", "KTRACE", NULL, 0, kvar, NULL, 8, KOFF(ki_traceflag), INT, "x", 0}, {"label", "LABEL", NULL, LJUST|DSIZ, label, s_label, SHRT_MAX, 0, CHAR, NULL, 0}, {"lim", "LIM", NULL, 0, maxrss, NULL, 5, 0, CHAR, NULL, 0}, {"lockname", "LOCK", NULL, LJUST, lockname, NULL, 6, 0, CHAR, NULL, 0}, {"login", "LOGIN", NULL, LJUST, logname, NULL, MAXLOGNAME-1, 0, CHAR, NULL, 0}, {"logname", "", "login", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"lstart", "STARTED", NULL, LJUST|USER, lstarted, NULL, 28, 0, CHAR, NULL, 0}, {"lwp", "LWP", NULL, 0, kvar, NULL, LWPLEN, KOFF(ki_tid), UINT, LWPFMT, 0}, {"majflt", "MAJFLT", NULL, USER, rvar, NULL, 4, ROFF(ru_majflt), LONG, "ld", 0}, {"minflt", "MINFLT", NULL, USER, rvar, NULL, 4, ROFF(ru_minflt), LONG, "ld", 0}, {"msgrcv", "MSGRCV", NULL, USER, rvar, NULL, 4, ROFF(ru_msgrcv), LONG, "ld", 0}, {"msgsnd", "MSGSND", NULL, USER, rvar, NULL, 4, ROFF(ru_msgsnd), LONG, "ld", 0}, {"mwchan", "MWCHAN", NULL, LJUST, mwchan, NULL, 6, 0, CHAR, NULL, 0}, {"ni", "", "nice", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"nice", "NI", NULL, 0, kvar, NULL, 2, KOFF(ki_nice), CHAR, "d", 0}, {"nivcsw", "NIVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nivcsw), LONG, "ld", 0}, {"nlwp", "NLWP", NULL, 0, kvar, NULL, NLWPLEN, KOFF(ki_numthreads), UINT, NLWPFMT, 0}, {"nsignals", "", "nsigs", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"nsigs", "NSIGS", NULL, USER, rvar, NULL, 4, ROFF(ru_nsignals), LONG, "ld", 0}, {"nswap", "NSWAP", NULL, USER, rvar, NULL, 4, ROFF(ru_nswap), LONG, "ld", 0}, {"nvcsw", "NVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw), LONG, "ld", 0}, {"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, 8, 0, CHAR, NULL, 0}, {"oublk", "OUBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_oublock), LONG, "ld", 0}, {"oublock", "", "oublk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"paddr", "PADDR", NULL, 0, kvar, NULL, 8, KOFF(ki_paddr), KPTR, "lx", 0}, {"pagein", "PAGEIN", NULL, USER, pagein, NULL, 6, 0, CHAR, NULL, 0}, {"pcpu", "", "%cpu", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"pending", "", "sig", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"pgid", "PGID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_pgid), UINT, PIDFMT, 0}, {"pid", "PID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_pid), UINT, PIDFMT, 0}, {"pmem", "", "%mem", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"ppid", "PPID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_ppid), UINT, PIDFMT, 0}, {"pri", "PRI", NULL, 0, pri, NULL, 3, 0, CHAR, NULL, 0}, {"re", "RE", NULL, INF127, kvar, NULL, 3, KOFF(ki_swtime), UINT, "d", 0}, {"rgid", "RGID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_rgid), UINT, UIDFMT, 0}, {"rgroup", "RGROUP", NULL, LJUST|DSIZ, rgroupname, s_rgroupname, USERLEN, 0, CHAR, NULL, 0}, {"rss", "RSS", NULL, 0, kvar, NULL, 4, KOFF(ki_rssize), PGTOK, "ld", 0}, {"rtprio", "RTPRIO", NULL, 0, priorityr, NULL, 7, KOFF(ki_pri), CHAR, NULL, 0}, {"ruid", "RUID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_ruid), UINT, UIDFMT, 0}, {"ruser", "RUSER", NULL, LJUST|DSIZ, runame, s_runame, USERLEN, 0, CHAR, NULL, 0}, {"sid", "SID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_sid), UINT, PIDFMT, 0}, {"sig", "PENDING", NULL, 0, kvar, NULL, 8, KOFF(ki_siglist), INT, "x", 0}, {"sigcatch", "CAUGHT", NULL, 0, kvar, NULL, 8, KOFF(ki_sigcatch), UINT, "x", 0}, {"sigignore", "IGNORED", NULL, 0, kvar, NULL, 8, KOFF(ki_sigignore), UINT, "x", 0}, {"sigmask", "BLOCKED", NULL, 0, kvar, NULL, 8, KOFF(ki_sigmask), UINT, "x", 0}, {"sl", "SL", NULL, INF127, kvar, NULL, 3, KOFF(ki_slptime), UINT, "d", 0}, {"start", "STARTED", NULL, LJUST|USER, started, NULL, 7, 0, CHAR, NULL, 0}, {"stat", "", "state", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"state", "STAT", NULL, 0, state, NULL, 4, 0, CHAR, NULL, 0}, {"svgid", "SVGID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_svgid), UINT, UIDFMT, 0}, {"svuid", "SVUID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_svuid), UINT, UIDFMT, 0}, {"tdev", "TDEV", NULL, 0, tdev, NULL, 4, 0, CHAR, NULL, 0}, {"time", "TIME", NULL, USER, cputime, NULL, 9, 0, CHAR, NULL, 0}, {"tpgid", "TPGID", NULL, 0, kvar, NULL, 4, KOFF(ki_tpgid), UINT, PIDFMT, 0}, {"tsid", "TSID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_tsid), UINT, PIDFMT, 0}, {"tsiz", "TSIZ", NULL, 0, kvar, NULL, 4, KOFF(ki_tsize), PGTOK, "ld", 0}, {"tt", "TT ", NULL, 0, tname, NULL, 4, 0, CHAR, NULL, 0}, {"tty", "TTY", NULL, LJUST, longtname, NULL, 8, 0, CHAR, NULL, 0}, {"ucomm", "UCOMM", NULL, LJUST, ucomm, NULL, MAXCOMLEN, 0, CHAR, NULL, 0}, {"uid", "UID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_uid), UINT, UIDFMT, 0}, - {"upr", "UPR", NULL, 0, kvar, NULL, 3, KOFF(ki_pri.pri_user), UCHAR, - "d", 0}, + {"upr", "UPR", NULL, 0, upr, NULL, 3, 0, CHAR, NULL, 0}, {"uprocp", "UPROCP", NULL, 0, kvar, NULL, 8, KOFF(ki_paddr), KPTR, "lx", 0}, {"user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN, 0, CHAR, NULL, 0}, {"usrpri", "", "upr", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"vsize", "", "vsz", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"vsz", "VSZ", NULL, 0, vsize, NULL, 5, 0, CHAR, NULL, 0}, {"wchan", "WCHAN", NULL, LJUST, wchan, NULL, 6, 0, CHAR, NULL, 0}, {"xstat", "XSTAT", NULL, 0, kvar, NULL, 4, KOFF(ki_xstat), USHORT, "x", 0}, {"", NULL, NULL, 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, }; void showkey(void) { VAR *v; int i; const char *p, *sep; i = 0; sep = ""; for (v = var; *(p = v->name); ++v) { int len = strlen(p); if (termwidth && (i += len + 1) > termwidth) { i = len; sep = "\n"; } (void) printf("%s%s", sep, p); sep = " "; } (void) printf("\n"); } void parsefmt(const char *p, int user) { static struct varent *vtail; char *tempstr, *tempstr1; #define FMTSEP " \t,\n" tempstr1 = tempstr = strdup(p); while (tempstr && *tempstr) { char *cp, *hp; VAR *v; struct varent *vent; /* * If an item contains an equals sign, it specifies a column * header, may contain embedded separator characters and * is always the last item. */ if (tempstr[strcspn(tempstr, "="FMTSEP)] != '=') while ((cp = strsep(&tempstr, FMTSEP)) != NULL && *cp == '\0') /* void */; else { cp = tempstr; tempstr = NULL; } if (cp == NULL || !(v = findvar(cp, user, &hp))) continue; if (!user) { /* * If the user is NOT adding this field manually, * get on with our lives if this VAR is already * represented in the list. */ vent = find_varentry(v); if (vent != NULL) continue; } if ((vent = malloc(sizeof(struct varent))) == NULL) errx(1, "malloc failed"); vent->header = v->header; if (hp) { hp = strdup(hp); if (hp) vent->header = hp; } vent->var = malloc(sizeof(*vent->var)); if (vent->var == NULL) errx(1, "malloc failed"); memcpy(vent->var, v, sizeof(*vent->var)); vent->next = NULL; if (vhead == NULL) vhead = vtail = vent; else { vtail->next = vent; vtail = vent; } } free(tempstr1); if (!vhead) { warnx("no valid keywords; valid keywords:"); showkey(); exit(1); } } static VAR * findvar(char *p, int user, char **header) { VAR *v, key; char *hp; hp = strchr(p, '='); if (hp) *hp++ = '\0'; key.name = p; v = bsearch(&key, var, sizeof(var)/sizeof(VAR) - 1, sizeof(VAR), vcmp); if (v && v->alias) { if (hp) { warnx("%s: illegal keyword specification", p); eval = 1; } parsefmt(v->alias, user); return ((VAR *)NULL); } if (!v) { warnx("%s: keyword not found", p); eval = 1; } if (header) *header = hp; return (v); } static int vcmp(const void *a, const void *b) { return (strcmp(((const VAR *)a)->name, ((const VAR *)b)->name)); } Index: head/bin/ps/print.c =================================================================== --- head/bin/ps/print.c (revision 130973) +++ head/bin/ps/print.c (revision 130974) @@ -1,808 +1,820 @@ /*- * 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. * 4. 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. */ #if 0 #ifndef lint static char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ps.h" #define ps_pgtok(a) (((a) * getpagesize()) / 1024) void printheader(void) { VAR *v; struct varent *vent; int allempty; allempty = 1; for (vent = vhead; vent; vent = vent->next) if (*vent->header != '\0') { allempty = 0; break; } if (allempty) return; for (vent = vhead; vent; vent = vent->next) { v = vent->var; if (v->flag & LJUST) { if (vent->next == NULL) /* last one */ (void)printf("%s", vent->header); else (void)printf("%-*s", v->width, vent->header); } else (void)printf("%*s", v->width, vent->header); if (vent->next != NULL) (void)putchar(' '); } (void)putchar('\n'); } void arguments(KINFO *k, VARENT *ve) { VAR *v; int left; char *cp, *vis_args; v = ve->var; 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 (ve->next == NULL) { /* last field */ if (termwidth == UNLIMITED) { (void)printf("%s", vis_args); } else { left = termwidth - (totwidth - v->width); if (left < 1) /* already wrapped, just use std width */ left = v->width; for (cp = vis_args; --left >= 0 && *cp != '\0';) (void)putchar(*cp++); } } else { (void)printf("%-*.*s", v->width, v->width, vis_args); } free(vis_args); } void command(KINFO *k, VARENT *ve) { VAR *v; int left; char *cp, *vis_env, *vis_args; v = ve->var; if (cflag) { if (ve->next == NULL) /* last field, don't pad */ (void)printf("%s", k->ki_p->ki_comm); 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 (ve->next == NULL) { /* last field */ if (termwidth == UNLIMITED) { if (vis_env) (void)printf("%s ", vis_env); (void)printf("%s", vis_args); } else { left = termwidth - (totwidth - v->width); if (left < 1) /* already wrapped, just use std width */ left = v->width; if ((cp = vis_env) != NULL) { while (--left >= 0 && *cp) (void)putchar(*cp++); if (--left >= 0) putchar(' '); } for (cp = vis_args; --left >= 0 && *cp != '\0';) (void)putchar(*cp++); } } else /* XXX env? */ (void)printf("%-*.*s", v->width, v->width, vis_args); free(vis_args); if (vis_env != NULL) free(vis_env); } void ucomm(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; (void)printf("%-*s", v->width, k->ki_p->ki_comm); } void logname(KINFO *k, VARENT *ve) { VAR *v; char *s; v = ve->var; (void)printf("%-*s", v->width, (s = k->ki_p->ki_login, *s) ? s : "-"); } void state(KINFO *k, VARENT *ve) { int flag, sflag, tdflags; char *cp; VAR *v; char buf[16]; v = ve->var; flag = k->ki_p->ki_flag; sflag = k->ki_p->ki_sflag; tdflags = k->ki_p->ki_tdflags; /* XXXKSE */ cp = buf; switch (k->ki_p->ki_stat) { case SSTOP: *cp = 'T'; break; case SSLEEP: if (tdflags & TDF_SINTR) /* interruptable (long) */ *cp = k->ki_p->ki_slptime >= MAXSLP ? 'I' : 'S'; else *cp = 'D'; break; case SRUN: case SIDL: *cp = 'R'; break; case SWAIT: *cp = 'W'; break; case SLOCK: *cp = 'L'; break; case SZOMB: *cp = 'Z'; break; default: *cp = '?'; } cp++; if (!(sflag & PS_INMEM)) *cp++ = 'W'; if (k->ki_p->ki_nice < NZERO) *cp++ = '<'; else if (k->ki_p->ki_nice > NZERO) *cp++ = 'N'; if (flag & P_TRACED) *cp++ = 'X'; if (flag & P_WEXIT && k->ki_p->ki_stat != SZOMB) *cp++ = 'E'; if (flag & P_PPWAIT) *cp++ = 'V'; if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0) *cp++ = 'L'; if (k->ki_p->ki_kiflag & KI_SLEADER) *cp++ = 's'; if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid) *cp++ = '+'; if (flag & P_JAILED) *cp++ = 'J'; *cp = '\0'; (void)printf("%-*s", v->width, buf); } +#define scalepri(x) ((x) - PZERO) + void pri(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; - (void)printf("%*d", v->width, k->ki_p->ki_pri.pri_level - PZERO); + (void)printf("%*d", v->width, scalepri(k->ki_p->ki_pri.pri_level)); } + +void +upr(KINFO *k, VARENT *ve) +{ + VAR *v; + + v = ve->var; + (void)printf("%*d", v->width, scalepri(k->ki_p->ki_pri.pri_user)); +} +#undef scalepri void uname(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; (void)printf("%-*s", v->width, user_from_uid(k->ki_p->ki_uid, 0)); } int s_uname(KINFO *k) { return (strlen(user_from_uid(k->ki_p->ki_uid, 0))); } void rgroupname(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; (void)printf("%-*s", v->width, group_from_gid(k->ki_p->ki_rgid, 0)); } int s_rgroupname(KINFO *k) { return (strlen(group_from_gid(k->ki_p->ki_rgid, 0))); } void runame(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; (void)printf("%-*s", v->width, user_from_uid(k->ki_p->ki_ruid, 0)); } int s_runame(KINFO *k) { return (strlen(user_from_uid(k->ki_p->ki_ruid, 0))); } void tdev(KINFO *k, VARENT *ve) { VAR *v; dev_t dev; char buff[16]; v = ve->var; dev = k->ki_p->ki_tdev; if (dev == NODEV) (void)printf("%*s", v->width, "??"); else { (void)snprintf(buff, sizeof(buff), "%d/%d", major(dev), minor(dev)); (void)printf("%*s", v->width, buff); } } void tname(KINFO *k, VARENT *ve) { VAR *v; dev_t dev; char *ttname; v = ve->var; dev = k->ki_p->ki_tdev; if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) (void)printf("%*s ", v->width - 1, "??"); else { if (strncmp(ttname, "tty", 3) == 0 || strncmp(ttname, "cua", 3) == 0) ttname += 3; (void)printf("%*.*s%c", v->width - 1, v->width - 1, ttname, k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-'); } } void longtname(KINFO *k, VARENT *ve) { VAR *v; dev_t dev; char *ttname; v = ve->var; dev = k->ki_p->ki_tdev; if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) (void)printf("%-*s", v->width, "??"); else (void)printf("%-*s", v->width, ttname); } void started(KINFO *k, VARENT *ve) { VAR *v; time_t then; struct tm *tp; static int use_ampm = -1; char buf[100]; v = ve->var; if (!k->ki_valid) { (void)printf("%-*s", v->width, "-"); return; } if (use_ampm < 0) use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0'); then = k->ki_p->ki_start.tv_sec; tp = localtime(&then); if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) { (void)strftime(buf, sizeof(buf), use_ampm ? "%l:%M%p" : "%k:%M ", tp); } else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) { (void)strftime(buf, sizeof(buf), use_ampm ? "%a%I%p" : "%a%H ", tp); } else (void)strftime(buf, sizeof(buf), "%e%b%y", tp); (void)printf("%-*s", v->width, buf); } void lstarted(KINFO *k, VARENT *ve) { VAR *v; time_t then; char buf[100]; v = ve->var; if (!k->ki_valid) { (void)printf("%-*s", v->width, "-"); return; } then = k->ki_p->ki_start.tv_sec; (void)strftime(buf, sizeof(buf), "%c", localtime(&then)); (void)printf("%-*s", v->width, buf); } void lockname(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { if (k->ki_p->ki_lockname[0] != 0) (void)printf("%-*.*s", v->width, v->width, k->ki_p->ki_lockname); else (void)printf("%-*s", v->width, "???"); } else (void)printf("%-*s", v->width, "-"); } void wchan(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; if (k->ki_p->ki_wchan) { if (k->ki_p->ki_wmesg[0] != 0) (void)printf("%-*.*s", v->width, v->width, k->ki_p->ki_wmesg); else (void)printf("%-*lx", v->width, (long)k->ki_p->ki_wchan); } else (void)printf("%-*s", v->width, "-"); } void nwchan(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; if (k->ki_p->ki_wchan) { (void)printf("%0*lx", v->width, (long)k->ki_p->ki_wchan); } else (void)printf("%-*s", v->width, "-"); } void mwchan(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; if (k->ki_p->ki_wchan) { if (k->ki_p->ki_wmesg[0] != 0) (void)printf("%-*.*s", v->width, v->width, k->ki_p->ki_wmesg); else (void)printf("%-*lx", v->width, (long)k->ki_p->ki_wchan); } else if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { if (k->ki_p->ki_lockname[0]) { (void)printf("%-*.*s", v->width, v->width, k->ki_p->ki_lockname); } else (void)printf("%-*s", v->width, "???"); } else (void)printf("%-*s", v->width, "-"); } void vsize(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; (void)printf("%*lu", v->width, (u_long)(k->ki_p->ki_size / 1024)); } void cputime(KINFO *k, VARENT *ve) { VAR *v; long secs; long psecs; /* "parts" of a second. first micro, then centi */ char obuff[128]; static char decimal_point; if (decimal_point == '\0') decimal_point = localeconv()->decimal_point[0]; v = ve->var; if (!k->ki_valid) { secs = 0; psecs = 0; } else { /* * 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->ki_p->ki_runtime / 1000000; psecs = k->ki_p->ki_runtime % 1000000; if (sumrusage) { secs += k->ki_p->ki_childtime.tv_sec; psecs += k->ki_p->ki_childtime.tv_usec; } /* * round and scale to 100's */ psecs = (psecs + 5000) / 10000; secs += psecs / 100; psecs = psecs % 100; } (void)snprintf(obuff, sizeof(obuff), "%3ld:%02ld%c%02ld", secs / 60, secs % 60, decimal_point, psecs); (void)printf("%*s", v->width, obuff); } void elapsed(KINFO *k, VARENT *ve) { VAR *v; time_t val; int days, hours, mins, secs; char obuff[128]; v = ve->var; val = now - k->ki_p->ki_start.tv_sec; days = val / (24 * 60 * 60); val %= 24 * 60 * 60; hours = val / (60 * 60); val %= 60 * 60; mins = val / 60; secs = val % 60; if (days != 0) (void)snprintf(obuff, sizeof(obuff), "%3d-%02d:%02d:%02d", days, hours, mins, secs); else if (hours != 0) (void)snprintf(obuff, sizeof(obuff), "%02d:%02d:%02d", hours, mins, secs); else (void)snprintf(obuff, sizeof(obuff), "%02d:%02d", mins, secs); (void)printf("%*s", v->width, obuff); } double getpcpu(const KINFO *k) { static int failure; if (!nlistread) failure = donlist(); if (failure) return (0.0); #define fxtofl(fixpt) ((double)(fixpt) / fscale) /* XXX - I don't like this */ if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_sflag & PS_INMEM) == 0) return (0.0); if (rawcpu) return (100.0 * fxtofl(k->ki_p->ki_pctcpu)); return (100.0 * fxtofl(k->ki_p->ki_pctcpu) / (1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu))))); } void pcpu(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; (void)printf("%*.1f", v->width, getpcpu(k)); } static double getpmem(KINFO *k) { static int failure; double fracmem; if (!nlistread) failure = donlist(); if (failure) return (0.0); if ((k->ki_p->ki_sflag & PS_INMEM) == 0) return (0.0); /* XXX want pmap ptpages, segtab, etc. (per architecture) */ /* XXX don't have info about shared */ fracmem = ((float)k->ki_p->ki_rssize) / mempages; return (100.0 * fracmem); } void pmem(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; (void)printf("%*.1f", v->width, getpmem(k)); } void pagein(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; (void)printf("%*ld", v->width, k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0); } /* ARGSUSED */ void maxrss(KINFO *k __unused, VARENT *ve) { VAR *v; v = ve->var; /* XXX not yet */ (void)printf("%*s", v->width, "-"); } void priorityr(KINFO *k, VARENT *ve) { VAR *v; struct priority *lpri; char str[8]; unsigned class, level; v = ve->var; lpri = &k->ki_p->ki_pri; class = lpri->pri_class; level = lpri->pri_level; switch (class) { case PRI_REALTIME: snprintf(str, sizeof(str), "real:%u", level); break; case PRI_TIMESHARE: strncpy(str, "normal", sizeof(str)); break; case PRI_IDLE: snprintf(str, sizeof(str), "idle:%u", level); break; default: snprintf(str, sizeof(str), "%u:%u", class, level); break; } str[sizeof(str) - 1] = '\0'; (void)printf("%*s", v->width, str); } /* * Generic output routines. Print fields from various prototype * structures. */ static void printval(void *bp, VAR *v) { static char ofmt[32] = "%"; const char *fcp; char *cp; cp = ofmt + 1; fcp = v->fmt; if (v->flag & LJUST) *cp++ = '-'; *cp++ = '*'; while ((*cp++ = *fcp++)); #define CHKINF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) switch (v->type) { case CHAR: (void)printf(ofmt, v->width, *(char *)bp); break; case UCHAR: (void)printf(ofmt, v->width, *(u_char *)bp); break; case SHORT: (void)printf(ofmt, v->width, *(short *)bp); break; case USHORT: (void)printf(ofmt, v->width, *(u_short *)bp); break; case INT: (void)printf(ofmt, v->width, *(int *)bp); break; case UINT: (void)printf(ofmt, v->width, CHKINF127(*(u_int *)bp)); break; case LONG: (void)printf(ofmt, v->width, *(long *)bp); break; case ULONG: (void)printf(ofmt, v->width, *(u_long *)bp); break; case KPTR: (void)printf(ofmt, v->width, *(u_long *)bp); break; case PGTOK: (void)printf(ofmt, v->width, ps_pgtok(*(u_long *)bp)); break; default: errx(1, "unknown type %d", v->type); } } void kvar(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; printval((char *)((char *)k->ki_p + v->off), v); } void rvar(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; if (k->ki_valid) printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v); else (void)printf("%*s", v->width, "-"); } void emulname(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; printf("%-*s", v->width, *k->ki_p->ki_emul ? k->ki_p->ki_emul : "-"); } void label(KINFO *k, VARENT *ve) { char *string; VAR *v; mac_t proclabel; int error; v = ve->var; string = NULL; if (mac_prepare_process_label(&proclabel) == -1) { perror("mac_prepare_process_label"); goto out; } error = mac_get_pid(k->ki_p->ki_pid, proclabel); if (error == 0) { if (mac_to_text(proclabel, &string) == -1) string = NULL; } mac_free(proclabel); out: if (string != NULL) { (void)printf("%-*s", v->width, string); free(string); } else (void)printf("%-*s", v->width, " -"); return; } int s_label(KINFO *k) { char *string = NULL; mac_t proclabel; int error, size = 0; if (mac_prepare_process_label(&proclabel) == -1) { perror("mac_prepare_process_label"); return (0); } error = mac_get_pid(k->ki_p->ki_pid, proclabel); if (error == 0 && mac_to_text(proclabel, &string) == 0) { size = strlen(string); free(string); } mac_free(proclabel); return (size); }