keyword.c revision 36352
11573Srgrimes/*-
21573Srgrimes * Copyright (c) 1990, 1993, 1994
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 3. All advertising materials mentioning features or use of this software
141573Srgrimes *    must display the following acknowledgement:
151573Srgrimes *	This product includes software developed by the University of
16148834Sstefanf *	California, Berkeley and its contributors.
171573Srgrimes * 4. Neither the name of the University nor the names of its contributors
181573Srgrimes *    may be used to endorse or promote products derived from this software
191573Srgrimes *    without specific prior written permission.
201573Srgrimes *
211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3184260Sobrien * SUCH DAMAGE.
32148834Sstefanf */
331573Srgrimes
341573Srgrimes#ifndef lint
351573Srgrimes#if 0
361573Srgrimesstatic char sccsid[] = "@(#)keyword.c	8.5 (Berkeley) 4/2/94";
371573Srgrimes#else
3884260Sobrienstatic const char rcsid[] =
3984260Sobrien	"$Id: keyword.c,v 1.18 1997/08/11 02:41:02 steve Exp $";
401573Srgrimes#endif
411573Srgrimes#endif /* not lint */
421573Srgrimes
431573Srgrimes#include <sys/param.h>
441573Srgrimes#include <sys/time.h>
451573Srgrimes#include <sys/resource.h>
461573Srgrimes#include <sys/proc.h>
471573Srgrimes#include <sys/sysctl.h>
481573Srgrimes#include <sys/ucred.h>
4984260Sobrien#include <sys/user.h>
5084260Sobrien
511573Srgrimes#include <err.h>
5284260Sobrien#include <errno.h>
5326926Smsmith#include <stddef.h>
541573Srgrimes#include <stdio.h>
551573Srgrimes#include <stdlib.h>
5684260Sobrien#include <string.h>
5784260Sobrien#include <utmp.h>
5884260Sobrien
5984260Sobrien#include "ps.h"
601573Srgrimes
611573Srgrimesstatic VAR *findvar __P((char *));
6284260Sobrienstatic int  vcmp __P((const void *, const void *));
6384260Sobrien
6484260Sobrien#ifdef NOTINUSE
6584260Sobrienint	utime(), stime(), ixrss(), idrss(), isrss();
6684260Sobrien	{{"utime"}, "UTIME", USER, utime, NULL, 4},
6784260Sobrien	{{"stime"}, "STIME", USER, stime, NULL, 4},
6884260Sobrien	{{"ixrss"}, "IXRSS", USER, ixrss, NULL, 4},
6984260Sobrien	{{"idrss"}, "IDRSS", USER, idrss, NULL, 4},
70148834Sstefanf	{{"isrss"}, "ISRSS", USER, isrss, NULL, 4},
7184260Sobrien#endif
7284260Sobrien
7384260Sobrien/* Compute offset in common structures. */
741573Srgrimes#define	POFF(x)	offsetof(struct proc, x)
75148834Sstefanf#define	EOFF(x)	offsetof(struct eproc, x)
7684260Sobrien#define	UOFF(x)	offsetof(struct usave, x)
7784260Sobrien#define	ROFF(x)	offsetof(struct rusage, x)
7884260Sobrien
7984260Sobrien#define	UIDFMT	"u"
8084260Sobrien#define	UIDLEN	5
8184260Sobrien#define	PIDFMT	"d"
8284260Sobrien#define	PIDLEN	5
8384260Sobrien#define USERLEN UT_NAMESIZE
8484260Sobrien
85148834SstefanfVAR var[] = {
861573Srgrimes	{"%cpu", "%CPU", NULL, 0, pcpu, NULL, 4},
87148834Sstefanf	{"%mem", "%MEM", NULL, 0, pmem, NULL, 4},
8884260Sobrien	{"acflag", "ACFLG",
8984260Sobrien		NULL, 0, pvar, NULL, 3, POFF(p_acflag), USHORT, "x"},
9084260Sobrien	{"acflg", "", "acflag"},
911573Srgrimes	{"blocked", "", "sigmask"},
92148834Sstefanf	{"caught", "", "sigcatch"},
93148834Sstefanf	{"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16},
94148834Sstefanf	{"cpu", "CPU", NULL, 0, pvar, NULL, 3, POFF(p_estcpu), ULONG, "d"},
95148834Sstefanf	{"cputime", "", "time"},
961573Srgrimes	{"f", "F", NULL, 0, pvar, NULL, 7, POFF(p_flag), LONG, "x"},
97148834Sstefanf	{"flags", "", "f"},
98148834Sstefanf	{"ignored", "", "sigignore"},
9984260Sobrien	{"inblk", "INBLK",
10084260Sobrien		NULL, USER, rvar, NULL, 4, ROFF(ru_inblock), LONG, "d"},
101148834Sstefanf	{"inblock", "", "inblk"},
102148834Sstefanf	{"jobc", "JOBC", NULL, 0, evar, NULL, 4, EOFF(e_jobc), SHORT, "d"},
10384260Sobrien	{"ktrace", "KTRACE",
10484260Sobrien		NULL, 0, pvar, NULL, 8, POFF(p_traceflag), LONG, "x"},
10584260Sobrien	{"ktracep", "KTRACEP",
10684260Sobrien		NULL, 0, pvar, NULL, 8, POFF(p_tracep), LONG, "x"},
10784260Sobrien	{"lim", "LIM", NULL, 0, maxrss, NULL, 5},
10884260Sobrien	{"login", "LOGIN", NULL, LJUST, logname, NULL, MAXLOGNAME-1},
10984260Sobrien	{"logname", "", "login"},
1101573Srgrimes	{"lstart", "STARTED", NULL, LJUST|USER, lstarted, NULL, 28},
1111573Srgrimes	{"majflt", "MAJFLT",
1121573Srgrimes		NULL, USER, rvar, NULL, 4, ROFF(ru_majflt), LONG, "d"},
1131573Srgrimes	{"minflt", "MINFLT",
1141573Srgrimes		NULL, USER, rvar, NULL, 4, ROFF(ru_minflt), LONG, "d"},
1151573Srgrimes	{"msgrcv", "MSGRCV",
1161573Srgrimes		NULL, USER, rvar, NULL, 4, ROFF(ru_msgrcv), LONG, "d"},
1171573Srgrimes	{"msgsnd", "MSGSND",
11884260Sobrien		NULL, USER, rvar, NULL, 4, ROFF(ru_msgsnd), LONG, "d"},
11984260Sobrien	{"ni", "", "nice"},
12084260Sobrien	{"nice", "NI", NULL, 0, pvar, NULL, 2, POFF(p_nice), CHAR, "d"},
121148834Sstefanf	{"nivcsw", "NIVCSW",
1221573Srgrimes		NULL, USER, rvar, NULL, 5, ROFF(ru_nivcsw), LONG, "d"},
1231573Srgrimes	{"nsignals", "", "nsigs"},
124148834Sstefanf	{"nsigs", "NSIGS",
125148834Sstefanf		NULL, USER, rvar, NULL, 4, ROFF(ru_nsignals), LONG, "d"},
126148834Sstefanf	{"nswap", "NSWAP",
127148834Sstefanf		NULL, USER, rvar, NULL, 4, ROFF(ru_nswap), LONG, "d"},
12884260Sobrien	{"nvcsw", "NVCSW",
129148834Sstefanf		NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw), LONG, "d"},
130148834Sstefanf	{"nwchan", "WCHAN", NULL, 0, pvar, NULL, 6, POFF(p_wchan), KPTR, "x"},
131148834Sstefanf	{"oublk", "OUBLK",
1321573Srgrimes		NULL, USER, rvar, NULL, 4, ROFF(ru_oublock), LONG, "d"},
133148834Sstefanf	{"oublock", "", "oublk"},
13484260Sobrien	{"p_ru", "P_RU", NULL, 0, pvar, NULL, 6, POFF(p_ru), KPTR, "x"},
135148834Sstefanf	{"paddr", "PADDR", NULL, 0, evar, NULL, 6, EOFF(e_paddr), KPTR, "x"},
13684260Sobrien	{"pagein", "PAGEIN", NULL, USER, pagein, NULL, 6},
13784260Sobrien	{"pcpu", "", "%cpu"},
138148834Sstefanf	{"pending", "", "sig"},
139148834Sstefanf	{"pgid", "PGID",
14084260Sobrien		NULL, 0, evar, NULL, PIDLEN, EOFF(e_pgid), ULONG, PIDFMT},
14184260Sobrien	{"pid", "PID", NULL, 0, pvar, NULL, PIDLEN, POFF(p_pid), LONG, PIDFMT},
142148834Sstefanf	{"pmem", "", "%mem"},
143148834Sstefanf	{"ppid", "PPID",
144148834Sstefanf		NULL, 0, evar, NULL, PIDLEN, EOFF(e_ppid), LONG, PIDFMT},
14584260Sobrien	{"pri", "PRI", NULL, 0, pri, NULL, 3},
14684260Sobrien	{"re", "RE", NULL, 0, pvar, NULL, 3, POFF(p_swtime), ULONG, "d"},
1471573Srgrimes	{"rgid", "RGID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_rgid),
148148834Sstefanf		ULONG, UIDFMT},
149148834Sstefanf	{"rlink", "RLINK",
150148834Sstefanf		NULL, 0, pvar, NULL, 8, POFF(p_procq.tqe_prev), KPTR, "x"},
151148834Sstefanf	{"rss", "RSS", NULL, 0, p_rssize, NULL, 4},
152148834Sstefanf	{"rssize", "", "rsz"},
153148834Sstefanf	{"rsz", "RSZ", NULL, 0, rssize, NULL, 4},
154148834Sstefanf	{"rtprio", "RTPRIO", NULL, 0, rtprior, NULL, 7, POFF(p_rtprio)},
155148834Sstefanf	{"ruid", "RUID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_ruid),
1561573Srgrimes		ULONG, UIDFMT},
15784260Sobrien	{"ruser", "RUSER", NULL, LJUST|DSIZ, runame, s_runame, USERLEN},
15884260Sobrien	{"sess", "SESS", NULL, 0, evar, NULL, 6, EOFF(e_sess), KPTR, "x"},
15984260Sobrien	{"sig", "PENDING", NULL, 0, pvar, NULL, 8, POFF(p_siglist), LONG, "x"},
16084260Sobrien	{"sigcatch", "CAUGHT",
16184260Sobrien		NULL, 0, pvar, NULL, 8, POFF(p_sigcatch), LONG, "x"},
1621573Srgrimes	{"sigignore", "IGNORED",
16384260Sobrien		NULL, 0, pvar, NULL, 8, POFF(p_sigignore), LONG, "x"},
16484260Sobrien	{"sigmask", "BLOCKED",
16584260Sobrien		NULL, 0, pvar, NULL, 8, POFF(p_sigmask), LONG, "x"},
16684260Sobrien	{"sl", "SL", NULL, 0, pvar, NULL, 3, POFF(p_slptime), ULONG, "d"},
16784260Sobrien	{"start", "STARTED", NULL, LJUST|USER, started, NULL, 7},
16884260Sobrien	{"stat", "", "state"},
16984260Sobrien	{"state", "STAT", NULL, 0, state, NULL, 4},
17084260Sobrien	{"svgid", "SVGID", NULL, 0,
17184260Sobrien		evar, NULL, UIDLEN, EOFF(e_pcred.p_svgid), ULONG, UIDFMT},
17284260Sobrien	{"svuid", "SVUID", NULL, 0,
17384260Sobrien		evar, NULL, UIDLEN, EOFF(e_pcred.p_svuid), ULONG, UIDFMT},
17484260Sobrien	{"tdev", "TDEV", NULL, 0, tdev, NULL, 4},
17584260Sobrien	{"time", "TIME", NULL, USER, cputime, NULL, 9},
17684260Sobrien	{"tpgid", "TPGID",
17784260Sobrien		NULL, 0, evar, NULL, 4, EOFF(e_tpgid), ULONG, PIDFMT},
17884260Sobrien	{"tsess", "TSESS", NULL, 0, evar, NULL, 6, EOFF(e_tsess), KPTR, "x"},
17984260Sobrien	{"tsiz", "TSIZ", NULL, 0, tsize, NULL, 4},
18084260Sobrien	{"tt", "TT ", NULL, 0, tname, NULL, 4},
18184260Sobrien	{"tty", "TTY", NULL, LJUST, longtname, NULL, 8},
18284260Sobrien	{"ucomm", "UCOMM", NULL, LJUST, ucomm, NULL, MAXCOMLEN},
18384260Sobrien	{"uid", "UID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_ucred.cr_uid),
18484260Sobrien		ULONG, UIDFMT},
18584260Sobrien	{"upr", "UPR", NULL, 0, pvar, NULL, 3, POFF(p_usrpri), CHAR, "d"},
18684260Sobrien	{"user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN},
18784260Sobrien	{"usrpri", "", "upr"},
18884260Sobrien	{"vsize", "", "vsz"},
18984260Sobrien	{"vsz", "VSZ", NULL, 0, vsize, NULL, 5},
19084260Sobrien	{"wchan", "WCHAN", NULL, LJUST, wchan, NULL, 6},
19184260Sobrien	{"xstat", "XSTAT", NULL, 0, pvar, NULL, 4, POFF(p_xstat), USHORT, "x"},
19284260Sobrien	{""},
19384260Sobrien};
19484260Sobrien
19584260Sobrienvoid
19684260Sobrienshowkey()
19784260Sobrien{
19884260Sobrien	VAR *v;
19984260Sobrien	int i;
2001573Srgrimes	char *p, *sep;
2011573Srgrimes
2021573Srgrimes	i = 0;
20384260Sobrien	sep = "";
20484260Sobrien	for (v = var; *(p = v->name); ++v) {
2051573Srgrimes		int len = strlen(p);
20684260Sobrien		if (termwidth && (i += len + 1) > termwidth) {
20784260Sobrien			i = len;
20884260Sobrien			sep = "\n";
20984260Sobrien		}
21084260Sobrien		(void) printf("%s%s", sep, p);
21184260Sobrien		sep = " ";
21284260Sobrien	}
21384260Sobrien	(void) printf("\n");
21484260Sobrien}
21584260Sobrien
21684260Sobrienvoid
2171573Srgrimesparsefmt(p)
2181573Srgrimes	char *p;
21984260Sobrien{
2201573Srgrimes	static struct varent *vtail;
2211573Srgrimes
2221573Srgrimes#define	FMTSEP	" \t,\n"
22384260Sobrien	while (p && *p) {
22484260Sobrien		char *cp;
2251573Srgrimes		VAR *v;
22684260Sobrien		struct varent *vent;
22784260Sobrien
22884260Sobrien		while ((cp = strsep(&p, FMTSEP)) != NULL && *cp == '\0')
22984260Sobrien			/* void */;
23084260Sobrien		if (!(v = findvar(cp)))
23184260Sobrien			continue;
23284260Sobrien		if ((vent = malloc(sizeof(struct varent))) == NULL)
23384260Sobrien			err(1, NULL);
23484260Sobrien		vent->var = v;
23584260Sobrien		vent->next = NULL;
23684260Sobrien		if (vhead == NULL)
2371573Srgrimes			vhead = vtail = vent;
2381573Srgrimes		else {
23984260Sobrien			vtail->next = vent;
2401573Srgrimes			vtail = vent;
2411573Srgrimes		}
2421573Srgrimes	}
24384260Sobrien	if (!vhead)
24484260Sobrien		errx(1, "no valid keywords");
2451573Srgrimes}
24684260Sobrien
2471573Srgrimesstatic VAR *
248148834Sstefanffindvar(p)
24984260Sobrien	char *p;
25084260Sobrien{
25184260Sobrien	VAR *v, key;
2521573Srgrimes	char *hp;
253148834Sstefanf	int vcmp();
25484260Sobrien
25584260Sobrien	hp = strchr(p, '=');
25684260Sobrien	if (hp)
25784260Sobrien		*hp++ = '\0';
258148834Sstefanf
259148834Sstefanf	key.name = p;
260148834Sstefanf	v = bsearch(&key, var, sizeof(var)/sizeof(VAR) - 1, sizeof(VAR), vcmp);
26184260Sobrien
2621573Srgrimes	if (v && v->alias) {
2631573Srgrimes		if (hp) {
2641573Srgrimes			warnx("%s: illegal keyword specification", p);
2651573Srgrimes			eval = 1;
2661573Srgrimes		}
2671573Srgrimes		parsefmt(v->alias);
26884260Sobrien		return ((VAR *)NULL);
26984260Sobrien	}
2701573Srgrimes	if (!v) {
27184260Sobrien		warnx("%s: keyword not found", p);
2721573Srgrimes		eval = 1;
273148834Sstefanf	} else if (hp)
27484260Sobrien		v->header = hp;
27584260Sobrien	return (v);
27684260Sobrien}
27784260Sobrien
2781573Srgrimesstatic int
279148834Sstefanfvcmp(a, b)
28084260Sobrien        const void *a, *b;
28184260Sobrien{
28284260Sobrien        return (strcmp(((VAR *)a)->name, ((VAR *)b)->name));
28384260Sobrien}
284148834Sstefanf