diff --git a/bin/ps/extern.h b/bin/ps/extern.h index 723d7fcb85dd..ea4362eeadd9 100644 --- a/bin/ps/extern.h +++ b/bin/ps/extern.h @@ -1,94 +1,94 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * 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. * 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. * * @(#)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 showthreads, sumrusage, termwidth; extern STAILQ_HEAD(velisthead, varent) varlist; __BEGIN_DECLS char *arguments(KINFO *, VARENT *); char *command(KINFO *, VARENT *); char *cputime(KINFO *, VARENT *); char *cpunum(KINFO *, VARENT *); int donlist(void); char *elapsed(KINFO *, VARENT *); char *elapseds(KINFO *, VARENT *); char *emulname(KINFO *, VARENT *); VARENT *find_varentry(VAR *); const char *fmt_argv(char **, char *, char *, size_t); double getpcpu(const KINFO *); char *jailname(KINFO *, VARENT *); char *kvar(KINFO *, VARENT *); char *label(KINFO *, VARENT *); char *loginclass(KINFO *, VARENT *); char *logname(KINFO *, VARENT *); char *longtname(KINFO *, VARENT *); char *lstarted(KINFO *, VARENT *); char *maxrss(KINFO *, VARENT *); char *lockname(KINFO *, VARENT *); char *mwchan(KINFO *, VARENT *); char *nwchan(KINFO *, VARENT *); char *pagein(KINFO *, VARENT *); void parsefmt(const char *, int); char *pcpu(KINFO *, VARENT *); char *pmem(KINFO *, VARENT *); char *pri(KINFO *, VARENT *); void printheader(void); char *priorityr(KINFO *, VARENT *); char *egroupname(KINFO *, VARENT *); char *rgroupname(KINFO *, VARENT *); char *runame(KINFO *, VARENT *); char *rvar(KINFO *, VARENT *); void showkey(void); char *started(KINFO *, VARENT *); char *state(KINFO *, VARENT *); char *systime(KINFO *, VARENT *); char *tdev(KINFO *, VARENT *); char *tdnam(KINFO *, VARENT *); char *tname(KINFO *, VARENT *); char *ucomm(KINFO *, VARENT *); -char *uname(KINFO *, VARENT *); +char *username(KINFO *, VARENT *); char *upr(KINFO *, VARENT *); char *usertime(KINFO *, VARENT *); char *vsize(KINFO *, VARENT *); char *wchan(KINFO *, VARENT *); __END_DECLS diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c index 2a8382a2273e..e78cf984e455 100644 --- a/bin/ps/keyword.c +++ b/bin/ps/keyword.c @@ -1,376 +1,376 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * 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. */ #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 #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 LWPFMT "d" #define NLWPFMT "d" #define UIDFMT "u" #define PIDFMT "d" /* PLEASE KEEP THE TABLE BELOW SORTED ALPHABETICALLY!!! */ static VAR var[] = { {"%cpu", "%CPU", NULL, "percent-cpu", 0, pcpu, 0, CHAR, NULL, 0}, {"%mem", "%MEM", NULL, "percent-memory", 0, pmem, 0, CHAR, NULL, 0}, {"acflag", "ACFLG", NULL, "accounting-flag", 0, kvar, KOFF(ki_acflag), USHORT, "x", 0}, {"acflg", "", "acflag", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"args", "COMMAND", NULL, "arguments", COMM|LJUST|USER, arguments, 0, CHAR, NULL, 0}, {"blocked", "", "sigmask", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"caught", "", "sigcatch", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"class", "CLASS", NULL, "login-class", LJUST, loginclass, 0, CHAR, NULL, 0}, {"comm", "COMMAND", NULL, "command", LJUST, ucomm, 0, CHAR, NULL, 0}, {"command", "COMMAND", NULL, "command", COMM|LJUST|USER, command, 0, CHAR, NULL, 0}, {"cow", "COW", NULL, "copy-on-write-faults", 0, kvar, KOFF(ki_cow), UINT, "u", 0}, {"cpu", "C", NULL, "on-cpu", 0, cpunum, 0, CHAR, NULL, 0}, {"cputime", "", "time", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"dsiz", "DSIZ", NULL, "data-size", 0, kvar, KOFF(ki_dsize), PGTOK, "ld", 0}, {"egid", "", "gid", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"egroup", "", "group", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"emul", "EMUL", NULL, "emulation-envirnment", LJUST, emulname, 0, CHAR, NULL, 0}, {"etime", "ELAPSED", NULL, "elapsed-time", USER, elapsed, 0, CHAR, NULL, 0}, {"etimes", "ELAPSED", NULL, "elapsed-times", USER, elapseds, 0, CHAR, NULL, 0}, {"euid", "", "uid", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"f", "F", NULL, "flags", 0, kvar, KOFF(ki_flag), LONG, "lx", 0}, {"f2", "F2", NULL, "flags2", 0, kvar, KOFF(ki_flag2), INT, "08x", 0}, {"fib", "FIB", NULL, "fib", 0, kvar, KOFF(ki_fibnum), INT, "d", 0}, {"flags", "", "f", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"flags2", "", "f2", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"gid", "GID", NULL, "gid", 0, kvar, KOFF(ki_groups), UINT, UIDFMT, 0}, {"group", "GROUP", NULL, "group", LJUST, egroupname, 0, CHAR, NULL, 0}, {"ignored", "", "sigignore", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"inblk", "INBLK", NULL, "read-blocks", USER, rvar, ROFF(ru_inblock), LONG, "ld", 0}, {"inblock", "", "inblk", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"jail", "JAIL", NULL, "jail-name", LJUST, jailname, 0, CHAR, NULL, 0}, {"jid", "JID", NULL, "jail-id", 0, kvar, KOFF(ki_jid), INT, "d", 0}, {"jobc", "JOBC", NULL, "job-control-count", 0, kvar, KOFF(ki_jobc), SHORT, "d", 0}, {"ktrace", "KTRACE", NULL, "ktrace", 0, kvar, KOFF(ki_traceflag), INT, "x", 0}, {"label", "LABEL", NULL, "label", LJUST, label, 0, CHAR, NULL, 0}, {"lim", "LIM", NULL, "memory-limit", 0, maxrss, 0, CHAR, NULL, 0}, {"lockname", "LOCK", NULL, "lock-name", LJUST, lockname, 0, CHAR, NULL, 0}, {"login", "LOGIN", NULL, "login-name", LJUST, logname, 0, CHAR, NULL, 0}, {"logname", "", "login", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"lstart", "STARTED", NULL, "start-time", LJUST|USER, lstarted, 0, CHAR, NULL, 0}, {"lwp", "LWP", NULL, "thread-id", 0, kvar, KOFF(ki_tid), UINT, LWPFMT, 0}, {"majflt", "MAJFLT", NULL, "major-faults", USER, rvar, ROFF(ru_majflt), LONG, "ld", 0}, {"minflt", "MINFLT", NULL, "minor-faults", USER, rvar, ROFF(ru_minflt), LONG, "ld", 0}, {"msgrcv", "MSGRCV", NULL, "received-messages", USER, rvar, ROFF(ru_msgrcv), LONG, "ld", 0}, {"msgsnd", "MSGSND", NULL, "sent-messages", USER, rvar, ROFF(ru_msgsnd), LONG, "ld", 0}, {"mwchan", "MWCHAN", NULL, "wait-channel", LJUST, mwchan, 0, CHAR, NULL, 0}, {"ni", "", "nice", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"nice", "NI", NULL, "nice", 0, kvar, KOFF(ki_nice), CHAR, "d", 0}, {"nivcsw", "NIVCSW", NULL, "involuntary-context-switches", USER, rvar, ROFF(ru_nivcsw), LONG, "ld", 0}, {"nlwp", "NLWP", NULL, "threads", 0, kvar, KOFF(ki_numthreads), UINT, NLWPFMT, 0}, {"nsignals", "", "nsigs", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"nsigs", "NSIGS", NULL, "signals-taken", USER, rvar, ROFF(ru_nsignals), LONG, "ld", 0}, {"nswap", "NSWAP", NULL, "swaps", USER, rvar, ROFF(ru_nswap), LONG, "ld", 0}, {"nvcsw", "NVCSW", NULL, "voluntary-context-switches", USER, rvar, ROFF(ru_nvcsw), LONG, "ld", 0}, {"nwchan", "NWCHAN", NULL, "wait-channel-address", LJUST, nwchan, 0, CHAR, NULL, 0}, {"oublk", "OUBLK", NULL, "written-blocks", USER, rvar, ROFF(ru_oublock), LONG, "ld", 0}, {"oublock", "", "oublk", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"paddr", "PADDR", NULL, "process-address", 0, kvar, KOFF(ki_paddr), KPTR, "lx", 0}, {"pagein", "PAGEIN", NULL, "pageins", USER, pagein, 0, CHAR, NULL, 0}, {"pcpu", "", "%cpu", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"pending", "", "sig", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"pgid", "PGID", NULL, "process-group", 0, kvar, KOFF(ki_pgid), UINT, PIDFMT, 0}, {"pid", "PID", NULL, "pid", 0, kvar, KOFF(ki_pid), UINT, PIDFMT, 0}, {"pmem", "", "%mem", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"ppid", "PPID", NULL, "ppid", 0, kvar, KOFF(ki_ppid), UINT, PIDFMT, 0}, {"pri", "PRI", NULL, "priority", 0, pri, 0, CHAR, NULL, 0}, {"re", "RE", NULL, "residency-time", INF127, kvar, KOFF(ki_swtime), UINT, "d", 0}, {"rgid", "RGID", NULL, "real-gid", 0, kvar, KOFF(ki_rgid), UINT, UIDFMT, 0}, {"rgroup", "RGROUP", NULL, "real-group", LJUST, rgroupname, 0, CHAR, NULL, 0}, {"rss", "RSS", NULL, "rss", 0, kvar, KOFF(ki_rssize), PGTOK, "ld", 0}, {"rtprio", "RTPRIO", NULL, "realtime-priority", 0, priorityr, KOFF(ki_pri), CHAR, NULL, 0}, {"ruid", "RUID", NULL, "real-uid", 0, kvar, KOFF(ki_ruid), UINT, UIDFMT, 0}, {"ruser", "RUSER", NULL, "real-user", LJUST, runame, 0, CHAR, NULL, 0}, {"sid", "SID", NULL, "sid", 0, kvar, KOFF(ki_sid), UINT, PIDFMT, 0}, {"sig", "PENDING", NULL, "signals-pending", 0, kvar, KOFF(ki_siglist), INT, "x", 0}, {"sigcatch", "CAUGHT", NULL, "signals-caught", 0, kvar, KOFF(ki_sigcatch), UINT, "x", 0}, {"sigignore", "IGNORED", NULL, "signals-ignored", 0, kvar, KOFF(ki_sigignore), UINT, "x", 0}, {"sigmask", "BLOCKED", NULL, "signal-mask", 0, kvar, KOFF(ki_sigmask), UINT, "x", 0}, {"sl", "SL", NULL, "sleep-time", INF127, kvar, KOFF(ki_slptime), UINT, "d", 0}, {"ssiz", "SSIZ", NULL, "stack-size", 0, kvar, KOFF(ki_ssize), PGTOK, "ld", 0}, {"start", "STARTED", NULL, "start-time", LJUST|USER, started, 0, CHAR, NULL, 0}, {"stat", "", "state", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"state", "STAT", NULL, "state", LJUST, state, 0, CHAR, NULL, 0}, {"svgid", "SVGID", NULL, "saved-gid", 0, kvar, KOFF(ki_svgid), UINT, UIDFMT, 0}, {"svuid", "SVUID", NULL, "saved-uid", 0, kvar, KOFF(ki_svuid), UINT, UIDFMT, 0}, {"systime", "SYSTIME", NULL, "system-time", USER, systime, 0, CHAR, NULL, 0}, {"tdaddr", "TDADDR", NULL, "thread-address", 0, kvar, KOFF(ki_tdaddr), KPTR, "lx", 0}, {"tdev", "TDEV", NULL, "terminal-device", 0, tdev, 0, CHAR, NULL, 0}, {"tdnam", "", "tdname", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"tdname", "TDNAME", NULL, "thread-name", LJUST, tdnam, 0, CHAR, NULL, 0}, {"tid", "", "lwp", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"time", "TIME", NULL, "cpu-time", USER, cputime, 0, CHAR, NULL, 0}, {"tpgid", "TPGID", NULL, "terminal-process-gid", 0, kvar, KOFF(ki_tpgid), UINT, PIDFMT, 0}, {"tracer", "TRACER", NULL, "tracer", 0, kvar, KOFF(ki_tracer), UINT, PIDFMT, 0}, {"tsid", "TSID", NULL, "terminal-sid", 0, kvar, KOFF(ki_tsid), UINT, PIDFMT, 0}, {"tsiz", "TSIZ", NULL, "text-size", 0, kvar, KOFF(ki_tsize), PGTOK, "ld", 0}, {"tt", "TT ", NULL, "terminal-name", 0, tname, 0, CHAR, NULL, 0}, {"tty", "TTY", NULL, "tty", LJUST, longtname, 0, CHAR, NULL, 0}, {"ucomm", "UCOMM", NULL, "accounting-name", LJUST, ucomm, 0, CHAR, NULL, 0}, {"uid", "UID", NULL, "uid", 0, kvar, KOFF(ki_uid), UINT, UIDFMT, 0}, {"upr", "UPR", NULL, "user-priority", 0, upr, 0, CHAR, NULL, 0}, {"uprocp", "UPROCP", NULL, "process-address", 0, kvar, KOFF(ki_paddr), KPTR, "lx", 0}, - {"user", "USER", NULL, "user", LJUST, uname, 0, CHAR, NULL, 0}, + {"user", "USER", NULL, "user", LJUST, username, 0, CHAR, NULL, 0}, {"usertime", "USERTIME", NULL, "user-time", USER, usertime, 0, CHAR, NULL, 0}, {"usrpri", "", "upr", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"vmaddr", "VMADDR", NULL, "vmspace-address", 0, kvar, KOFF(ki_vmspace), KPTR, "lx", 0}, {"vsize", "", "vsz", NULL, 0, NULL, 0, CHAR, NULL, 0}, {"vsz", "VSZ", NULL, "virtual-size", 0, vsize, 0, CHAR, NULL, 0}, {"wchan", "WCHAN", NULL, "wait-channel", LJUST, wchan, 0, CHAR, NULL, 0}, {"xstat", "XSTAT", NULL, "exit-status", 0, kvar, KOFF(ki_xstat), USHORT, "x", 0}, {"", NULL, NULL, NULL, 0, NULL, 0, CHAR, NULL, 0}, }; void showkey(void) { VAR *v; int i; const char *p, *sep; i = 0; sep = ""; xo_open_list("key"); for (v = var; *(p = v->name); ++v) { int len = strlen(p); if (termwidth && (i += len + 1) > termwidth) { i = len; sep = "\n"; } xo_emit("{P:/%hs}{l:key/%hs}", sep, p); sep = " "; } xo_emit("\n"); xo_close_list("key"); xo_finish(); } void parsefmt(const char *p, int user) { 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)); STAILQ_INSERT_TAIL(&varlist, vent, next_ve); } free(tempstr1); if (STAILQ_EMPTY(&varlist)) { warnx("no valid keywords; valid keywords:"); showkey(); exit(1); } } static VAR * findvar(char *p, int user, char **header) { size_t rflen; VAR *v, key; char *hp, *realfmt; 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 the user specified an alternate-header for this * (aliased) format-name, then we need to copy that * alternate-header when making the recursive call to * process the alias. */ if (hp == NULL) parsefmt(v->alias, user); else { /* * XXX - This processing will not be correct for * any alias which expands into a list of format * keywords. Presently there are no aliases * which do that. */ rflen = strlen(v->alias) + strlen(hp) + 2; realfmt = malloc(rflen); if (realfmt == NULL) errx(1, "malloc failed"); snprintf(realfmt, rflen, "%s=%s", v->alias, hp); parsefmt(realfmt, user); free(realfmt); } 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)); } diff --git a/bin/ps/print.c b/bin/ps/print.c index 3d3a543c8a5d..2b61c6b0a15a 100644 --- a/bin/ps/print.c +++ b/bin/ps/print.c @@ -1,874 +1,874 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * 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. */ #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 #include #include #include #include "ps.h" #define COMMAND_WIDTH 16 #define ARGUMENTS_WIDTH 16 #define ps_pgtok(a) (((a) * getpagesize()) / 1024) void printheader(void) { VAR *v; struct varent *vent; STAILQ_FOREACH(vent, &varlist, next_ve) if (*vent->header != '\0') break; if (!vent) return; STAILQ_FOREACH(vent, &varlist, next_ve) { v = vent->var; if (v->flag & LJUST) { if (STAILQ_NEXT(vent, next_ve) == NULL) /* last one */ xo_emit("{T:/%hs}", vent->header); else xo_emit("{T:/%-*hs}", v->width, vent->header); } else xo_emit("{T:/%*hs}", v->width, vent->header); if (STAILQ_NEXT(vent, next_ve) != NULL) xo_emit("{P: }"); } xo_emit("\n"); } char * arguments(KINFO *k, VARENT *ve) { char *vis_args; if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) xo_errx(1, "malloc failed"); strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); if (STAILQ_NEXT(ve, next_ve) != NULL && strlen(vis_args) > ARGUMENTS_WIDTH) vis_args[ARGUMENTS_WIDTH] = '\0'; return (vis_args); } char * command(KINFO *k, VARENT *ve) { char *vis_args, *vis_env, *str; if (cflag) { /* If it is the last field, then don't pad */ if (STAILQ_NEXT(ve, next_ve) == NULL) { asprintf(&str, "%s%s%s%s%s", k->ki_d.prefix ? k->ki_d.prefix : "", k->ki_p->ki_comm, (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : "", (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_moretdname : ""); } else str = strdup(k->ki_p->ki_comm); return (str); } if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) xo_errx(1, "malloc failed"); strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field */ if (k->ki_env) { if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) == NULL) xo_errx(1, "malloc failed"); strvis(vis_env, k->ki_env, VIS_TAB | VIS_NL | VIS_NOSLASH); } else vis_env = NULL; asprintf(&str, "%s%s%s%s", k->ki_d.prefix ? k->ki_d.prefix : "", vis_env ? vis_env : "", vis_env ? " " : "", vis_args); if (vis_env != NULL) free(vis_env); free(vis_args); } else { /* ki_d.prefix & ki_env aren't shown for interim fields */ str = vis_args; if (strlen(str) > COMMAND_WIDTH) str[COMMAND_WIDTH] = '\0'; } return (str); } char * ucomm(KINFO *k, VARENT *ve) { char *str; if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field, don't pad */ asprintf(&str, "%s%s%s%s%s", k->ki_d.prefix ? k->ki_d.prefix : "", k->ki_p->ki_comm, (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : "", (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_moretdname : ""); } else { if (showthreads && k->ki_p->ki_numthreads > 1) asprintf(&str, "%s/%s%s", k->ki_p->ki_comm, k->ki_p->ki_tdname, k->ki_p->ki_moretdname); else str = strdup(k->ki_p->ki_comm); } return (str); } char * tdnam(KINFO *k, VARENT *ve __unused) { char *str; if (showthreads && k->ki_p->ki_numthreads > 1) asprintf(&str, "%s%s", k->ki_p->ki_tdname, k->ki_p->ki_moretdname); else str = strdup(" "); return (str); } char * logname(KINFO *k, VARENT *ve __unused) { if (*k->ki_p->ki_login == '\0') return (NULL); return (strdup(k->ki_p->ki_login)); } char * state(KINFO *k, VARENT *ve __unused) { long flag, tdflags; char *cp, *buf; buf = malloc(16); if (buf == NULL) xo_errx(1, "malloc failed"); flag = k->ki_p->ki_flag; 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 (!(flag & P_INMEM)) *cp++ = 'W'; if (k->ki_p->ki_nice < NZERO || k->ki_p->ki_pri.pri_class == PRI_REALTIME) *cp++ = '<'; else if (k->ki_p->ki_nice > NZERO || k->ki_p->ki_pri.pri_class == PRI_IDLE) *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_cr_flags & CRED_FLAG_CAPMODE) != 0) *cp++ = 'C'; 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'; return (buf); } #define scalepri(x) ((x) - PZERO) char * pri(KINFO *k, VARENT *ve __unused) { char *str; asprintf(&str, "%d", scalepri(k->ki_p->ki_pri.pri_level)); return (str); } char * upr(KINFO *k, VARENT *ve __unused) { char *str; asprintf(&str, "%d", scalepri(k->ki_p->ki_pri.pri_user)); return (str); } #undef scalepri char * -uname(KINFO *k, VARENT *ve __unused) +username(KINFO *k, VARENT *ve __unused) { return (strdup(user_from_uid(k->ki_p->ki_uid, 0))); } char * egroupname(KINFO *k, VARENT *ve __unused) { return (strdup(group_from_gid(k->ki_p->ki_groups[0], 0))); } char * rgroupname(KINFO *k, VARENT *ve __unused) { return (strdup(group_from_gid(k->ki_p->ki_rgid, 0))); } char * runame(KINFO *k, VARENT *ve __unused) { return (strdup(user_from_uid(k->ki_p->ki_ruid, 0))); } char * tdev(KINFO *k, VARENT *ve __unused) { dev_t dev; char *str; dev = k->ki_p->ki_tdev; if (dev == NODEV) str = strdup("-"); else asprintf(&str, "%#jx", (uintmax_t)dev); return (str); } char * tname(KINFO *k, VARENT *ve __unused) { dev_t dev; char *ttname, *str; dev = k->ki_p->ki_tdev; if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) str = strdup("- "); else { if (strncmp(ttname, "tty", 3) == 0 || strncmp(ttname, "cua", 3) == 0) ttname += 3; if (strncmp(ttname, "pts/", 4) == 0) ttname += 4; asprintf(&str, "%s%c", ttname, k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-'); } return (str); } char * longtname(KINFO *k, VARENT *ve __unused) { dev_t dev; const char *ttname; dev = k->ki_p->ki_tdev; if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) ttname = "-"; return (strdup(ttname)); } char * started(KINFO *k, VARENT *ve __unused) { time_t then; struct tm *tp; size_t buflen = 100; char *buf; if (!k->ki_valid) return (NULL); buf = malloc(buflen); if (buf == NULL) xo_errx(1, "malloc failed"); 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, buflen, "%H:%M ", tp); } else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) { (void)strftime(buf, buflen, "%a%H ", tp); } else (void)strftime(buf, buflen, "%e%b%y", tp); return (buf); } char * lstarted(KINFO *k, VARENT *ve __unused) { time_t then; char *buf; size_t buflen = 100; if (!k->ki_valid) return (NULL); buf = malloc(buflen); if (buf == NULL) xo_errx(1, "malloc failed"); then = k->ki_p->ki_start.tv_sec; (void)strftime(buf, buflen, "%c", localtime(&then)); return (buf); } char * lockname(KINFO *k, VARENT *ve __unused) { char *str; if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { if (k->ki_p->ki_lockname[0] != 0) str = strdup(k->ki_p->ki_lockname); else str = strdup("???"); } else str = NULL; return (str); } char * wchan(KINFO *k, VARENT *ve __unused) { char *str; if (k->ki_p->ki_wchan) { if (k->ki_p->ki_wmesg[0] != 0) str = strdup(k->ki_p->ki_wmesg); else asprintf(&str, "%lx", (long)k->ki_p->ki_wchan); } else str = NULL; return (str); } char * nwchan(KINFO *k, VARENT *ve __unused) { char *str; if (k->ki_p->ki_wchan) asprintf(&str, "%0lx", (long)k->ki_p->ki_wchan); else str = NULL; return (str); } char * mwchan(KINFO *k, VARENT *ve __unused) { char *str; if (k->ki_p->ki_wchan) { if (k->ki_p->ki_wmesg[0] != 0) str = strdup(k->ki_p->ki_wmesg); else asprintf(&str, "%lx", (long)k->ki_p->ki_wchan); } else if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { if (k->ki_p->ki_lockname[0]) { str = strdup(k->ki_p->ki_lockname); } else str = strdup("???"); } else str = NULL; return (str); } char * vsize(KINFO *k, VARENT *ve __unused) { char *str; asprintf(&str, "%lu", (u_long)(k->ki_p->ki_size / 1024)); return (str); } static char * printtime(KINFO *k, VARENT *ve __unused, long secs, long psecs) /* psecs is "parts" of a second. first micro, then centi */ { static char decimal_point; char *str; if (decimal_point == '\0') decimal_point = localeconv()->decimal_point[0]; if (!k->ki_valid) { secs = 0; psecs = 0; } else { /* round and scale to 100's */ psecs = (psecs + 5000) / 10000; secs += psecs / 100; psecs = psecs % 100; } asprintf(&str, "%ld:%02ld%c%02ld", secs / 60, secs % 60, decimal_point, psecs); return (str); } char * cputime(KINFO *k, VARENT *ve) { long secs, psecs; /* * 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; } return (printtime(k, ve, secs, psecs)); } char * cpunum(KINFO *k, VARENT *ve __unused) { char *cpu; if (k->ki_p->ki_stat == SRUN && k->ki_p->ki_oncpu != NOCPU) { asprintf(&cpu, "%d", k->ki_p->ki_oncpu); } else { asprintf(&cpu, "%d", k->ki_p->ki_lastcpu); } return (cpu); } char * systime(KINFO *k, VARENT *ve) { long secs, psecs; secs = k->ki_p->ki_rusage.ru_stime.tv_sec; psecs = k->ki_p->ki_rusage.ru_stime.tv_usec; if (sumrusage) { secs += k->ki_p->ki_childstime.tv_sec; psecs += k->ki_p->ki_childstime.tv_usec; } return (printtime(k, ve, secs, psecs)); } char * usertime(KINFO *k, VARENT *ve) { long secs, psecs; secs = k->ki_p->ki_rusage.ru_utime.tv_sec; psecs = k->ki_p->ki_rusage.ru_utime.tv_usec; if (sumrusage) { secs += k->ki_p->ki_childutime.tv_sec; psecs += k->ki_p->ki_childutime.tv_usec; } return (printtime(k, ve, secs, psecs)); } char * elapsed(KINFO *k, VARENT *ve __unused) { time_t val; int days, hours, mins, secs; char *str; if (!k->ki_valid) return (NULL); 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) asprintf(&str, "%3d-%02d:%02d:%02d", days, hours, mins, secs); else if (hours != 0) asprintf(&str, "%02d:%02d:%02d", hours, mins, secs); else asprintf(&str, "%02d:%02d", mins, secs); return (str); } char * elapseds(KINFO *k, VARENT *ve __unused) { time_t val; char *str; if (!k->ki_valid) return (NULL); val = now - k->ki_p->ki_start.tv_sec; asprintf(&str, "%jd", (intmax_t)val); return (str); } 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_flag & P_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))))); } char * pcpu(KINFO *k, VARENT *ve __unused) { char *str; asprintf(&str, "%.1f", getpcpu(k)); return (str); } static double getpmem(KINFO *k) { static int failure; double fracmem; if (!nlistread) failure = donlist(); if (failure) return (0.0); if ((k->ki_p->ki_flag & P_INMEM) == 0) return (0.0); /* XXX want pmap ptpages, segtab, etc. (per architecture) */ /* XXX don't have info about shared */ fracmem = ((double)k->ki_p->ki_rssize) / mempages; return (100.0 * fracmem); } char * pmem(KINFO *k, VARENT *ve __unused) { char *str; asprintf(&str, "%.1f", getpmem(k)); return (str); } char * pagein(KINFO *k, VARENT *ve __unused) { char *str; asprintf(&str, "%ld", k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0); return (str); } /* ARGSUSED */ char * maxrss(KINFO *k __unused, VARENT *ve __unused) { /* XXX not yet */ return (NULL); } char * priorityr(KINFO *k, VARENT *ve __unused) { struct priority *lpri; char *str; unsigned class, level; lpri = &k->ki_p->ki_pri; class = lpri->pri_class; level = lpri->pri_level; switch (class) { case RTP_PRIO_REALTIME: /* alias for PRI_REALTIME */ asprintf(&str, "real:%u", level - PRI_MIN_REALTIME); break; case RTP_PRIO_NORMAL: /* alias for PRI_TIMESHARE */ if (level >= PRI_MIN_TIMESHARE) asprintf(&str, "normal:%u", level - PRI_MIN_TIMESHARE); else asprintf(&str, "kernel:%u", level - PRI_MIN_KERN); break; case RTP_PRIO_IDLE: /* alias for PRI_IDLE */ asprintf(&str, "idle:%u", level - PRI_MIN_IDLE); break; case RTP_PRIO_ITHD: /* alias for PRI_ITHD */ asprintf(&str, "intr:%u", level - PRI_MIN_ITHD); break; default: asprintf(&str, "%u:%u", class, level); break; } return (str); } /* * Generic output routines. Print fields from various prototype * structures. */ static char * printval(void *bp, VAR *v) { static char ofmt[32] = "%"; const char *fcp; char *cp, *str; cp = ofmt + 1; fcp = v->fmt; while ((*cp++ = *fcp++)); #define CHKINF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) switch (v->type) { case CHAR: (void)asprintf(&str, ofmt, *(char *)bp); break; case UCHAR: (void)asprintf(&str, ofmt, *(u_char *)bp); break; case SHORT: (void)asprintf(&str, ofmt, *(short *)bp); break; case USHORT: (void)asprintf(&str, ofmt, *(u_short *)bp); break; case INT: (void)asprintf(&str, ofmt, *(int *)bp); break; case UINT: (void)asprintf(&str, ofmt, CHKINF127(*(u_int *)bp)); break; case LONG: (void)asprintf(&str, ofmt, *(long *)bp); break; case ULONG: (void)asprintf(&str, ofmt, *(u_long *)bp); break; case KPTR: (void)asprintf(&str, ofmt, *(u_long *)bp); break; case PGTOK: (void)asprintf(&str, ofmt, ps_pgtok(*(u_long *)bp)); break; } return (str); } char * kvar(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; return (printval((char *)((char *)k->ki_p + v->off), v)); } char * rvar(KINFO *k, VARENT *ve) { VAR *v; v = ve->var; if (!k->ki_valid) return (NULL); return (printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v)); } char * emulname(KINFO *k, VARENT *ve __unused) { return (strdup(k->ki_p->ki_emul)); } char * label(KINFO *k, VARENT *ve __unused) { char *string; mac_t proclabel; int error; string = NULL; if (mac_prepare_process_label(&proclabel) == -1) { xo_warn("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: return (string); } char * loginclass(KINFO *k, VARENT *ve __unused) { /* * Don't display login class for system processes; * login classes are used for resource limits, * and limits don't apply to system processes. */ if (k->ki_p->ki_flag & P_SYSTEM) { return (strdup("-")); } return (strdup(k->ki_p->ki_loginclass)); } char * jailname(KINFO *k, VARENT *ve __unused) { char *name; if (k->ki_p->ki_jid == 0) return (strdup("-")); name = jail_getname(k->ki_p->ki_jid); if (name == NULL) return (strdup("-")); return (name); }