Date: Tue, 11 Jun 2002 05:08:57 +0200 From: Cyrille Lefevre <cyrille.lefevre@laposte.net> To: "J. Mallett" <jmallett@FreeBSD.org> Cc: standards@FreeBSD.org Subject: Re: cvs commit: www/en/projects/c99 index.sgml Message-ID: <20020611030857.GB14401@gits.dyndns.org> In-Reply-To: <20020606194448.A23497@FreeBSD.ORG> References: <200206070217.g572HH584853@freefall.freebsd.org> <20020606194448.A23497@FreeBSD.ORG>
next in thread | previous in thread | raw e-mail | index | archive | help
--/NkBOFFp2J2Af1nK Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Jun 06, 2002 at 07:44:49PM -0700, J. Mallett wrote: > * From Mike Barcroft <mike@FreeBSD.org> > > mike 2002/06/06 19:17:17 PDT > > > > Modified files: > > en/projects/c99 index.sgml > > Log: > > J. Mallett will be coordinating changes to ps(1). > > Which essentially means: If you have patches for ps(1) wrt SUSv3 conformance, > or want to discuss which options of ours should go in favor of SUSv3 ones that > conflict, which should be optional, etc., speak up. well, I'm a lot disapointed about your nomination while I ask for it last week. I suppose you get the maintainership of ps(1) because you are a commiter ? whatever, here is, in attachment, the current version of ps(1) I'm working on. PS : I've tryed to subscribe to this list twince w/o success, any ideas ? Cyrille. -- Cyrille Lefevre mailto:cyrille.lefevre@laposte.net --/NkBOFFp2J2Af1nK Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=NOTES ps compatible pre-BSD44, BSD44 and SUSV2 first of all, this code has been made last year and is based on -stable version of ps(1). since then, I never posted it before because it's conformance to SUSV2 (now SUSV3) needs to be checked. this need always to be done and I will do it w/in the next days (weeks?). in the meantime, I'll write a more detailled note about differences between BSD and SUSV3 ps(1). also, the manual would have to be updated to reflect the reallity (any volunteer ? :). old compilation flags : BACKWARD_COMPATIBILITY convert pre BSD44 options (w/o dash) to BSD44 ones. LAZY_PS enable option -f to show command line and environment information about swapped out processes else, the -f option is implied. new compilation flags : COMPAT_BSD44 be strictly compatible w/ BSD44 ps, else : * -p, -t and -U respectively accept a list of pids, ttys or users instead of a single one. * -t accept ttyXX in addition to /dev/ttyXX and XX. * -U also accept uids in addition of user names. * output is formated more intelligently when combining options such as -j, -l, -u and -v. format strings are combined instead of being concatenated. * -o keyword=header now works for aliased keywords, also, -o keyword= don't print an empty line anymore, if any. COMPAT_SUSV2 be compatible w/ SUSV2 ps if the SUSV2 environment variable has a non-zero value or if called as ps5. this may be overriden using the new -B (BSD) or -V (SUSV2) options. SUSV2 is automagically disabled when using pre BSD44 options. SUSV2 options are, in fact, almost the SYSV ones. here is the usage string : usage: ps [-AaBdefjl] [-C cmdlist] [-g pgrplist] [-G grouplist] [-o fmt] [-p pidlist] [-t ttylist] [-u userlist] [-U userlist] [-m core] [-n system] [-w swap] here are the new -o keywords w/ their BSD44 counterpart, if any, in parentheses : addr (paddr), args (command), c, comm (command), etime, group, l (state), rgroup and stime. and the ones which are affected when SUSV2 is enable : pri and time. NO_SWAP disable -W option since kvm(3) doesn't read swap for almost 10 years. also, single-linked tail queues have been converted to queue(3). --/NkBOFFp2J2Af1nK Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ps-stable.patch" Index: Makefile =================================================================== RCS file: /home/ncvs/src/bin/ps/Makefile,v retrieving revision 1.13 diff -u -r1.13 Makefile --- Makefile 17 Nov 1999 13:37:30 -0000 1.13 +++ Makefile 11 Jun 2002 03:02:38 -0000 @@ -9,7 +9,12 @@ # keep ps from being an unnecessary load # on large systems. # -CFLAGS+=-I${.CURDIR}/../../sys -DLAZY_PS +CFLAGS= -g +CFLAGS+= -I${.CURDIR}/../../sys +CFLAGS+= -DBACKWARD_COMPATIBILITY +CFLAGS+= -DLAZY_PS +# CFLAGS+= -DCOMPAT_BSD44 +CFLAGS+= -DCOMPAT_SUSV2 DPADD= ${LIBM} ${LIBKVM} LDADD= -lm -lkvm #BINGRP= kmem Index: extern.h =================================================================== RCS file: /home/ncvs/src/bin/ps/extern.h,v retrieving revision 1.9 diff -u -r1.9 extern.h --- extern.h 27 Aug 1999 23:14:50 -0000 1.9 +++ extern.h 5 Jun 2001 01:16:06 -0000 @@ -34,45 +34,61 @@ * $FreeBSD: src/bin/ps/extern.h,v 1.9 1999/08/27 23:14:50 peter Exp $ */ -struct kinfo; -struct nlist; -struct var; -struct varent; - extern fixpt_t ccpu; extern int eval, fscale, mempages, nlistread, rawcpu, cflag; extern int sumrusage, termwidth, totwidth; extern VAR var[]; -extern VARENT *vhead; +extern VARLIST varlist; + +#if defined(COMPAT_SUSV2) +extern int susv2; +#endif __BEGIN_DECLS void command __P((KINFO *, VARENT *)); void cputime __P((KINFO *, VARENT *)); int donlist __P((void)); +#if defined(COMPAT_SUSV2) +void etime __P((KINFO *, VARENT *)); +#endif void evar __P((KINFO *, VARENT *)); char *fmt_argv __P((char **, char *, int)); double getpcpu __P((KINFO *)); -double getpmem __P((KINFO *)); +#if defined(COMPAT_SUSV2) +void gname __P((KINFO *, VARENT *)); +int s_gname __P((KINFO *)); +#endif void logname __P((KINFO *, VARENT *)); void longtname __P((KINFO *, VARENT *)); void lstarted __P((KINFO *, VARENT *)); void maxrss __P((KINFO *, VARENT *)); -void nlisterr __P((struct nlist *)); void p_rssize __P((KINFO *, VARENT *)); void pagein __P((KINFO *, VARENT *)); -void parsefmt __P((char *)); +#if defined(COMPAT_BSD44) +void bsd_parsefmt __P((char *)); +#endif +#if defined (COMPAT_SUSV2) +void susv2_parsefmt __P((char *, char *)); +#endif void pcpu __P((KINFO *, VARENT *)); void pmem __P((KINFO *, VARENT *)); void pri __P((KINFO *, VARENT *)); -void rtprior __P((KINFO *, VARENT *)); void printheader __P((void)); void pvar __P((KINFO *, VARENT *)); +#if defined(COMPAT_SUSV2) +void rgname __P((KINFO *, VARENT *)); +int s_rgname __P((KINFO *)); +#endif void rssize __P((KINFO *, VARENT *)); +void rtprior __P((KINFO *, VARENT *)); void runame __P((KINFO *, VARENT *)); int s_runame __P((KINFO *)); void rvar __P((KINFO *, VARENT *)); void showkey __P((void)); void started __P((KINFO *, VARENT *)); +#if defined(COMPAT_SUSV2) +void stime __P((KINFO *, VARENT *)); +#endif void state __P((KINFO *, VARENT *)); void tdev __P((KINFO *, VARENT *)); void tname __P((KINFO *, VARENT *)); Index: fmt.c =================================================================== RCS file: /home/ncvs/src/bin/ps/fmt.c,v retrieving revision 1.14.2.1 diff -u -r1.14.2.1 fmt.c --- fmt.c 16 Mar 2002 01:15:11 -0000 1.14.2.1 +++ fmt.c 25 May 2002 17:11:04 -0000 @@ -32,23 +32,23 @@ */ #ifndef lint +#include <sys/cdefs.h> #if 0 -static char sccsid[] = "@(#)fmt.c 8.4 (Berkeley) 4/15/94"; +__RCSID("@(#)fmt.c 8.4 (Berkeley) 4/15/94"); #endif -static const char rcsid[] = - "$FreeBSD: src/bin/ps/fmt.c,v 1.14.2.1 2002/03/16 01:15:11 mikeh Exp $"; +__FBSDID("$FreeBSD: src/bin/ps/fmt.c,v 1.14.2.1 2002/03/16 01:15:11 mikeh Exp $"); #endif /* not lint */ #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> + #include <err.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <vis.h> -#include "ps.h" static char *cmdpart __P((char *)); static char *shquote __P((char **)); Index: keyword.c =================================================================== RCS file: /home/ncvs/src/bin/ps/keyword.c,v retrieving revision 1.24.2.2 diff -u -r1.24.2.2 keyword.c --- keyword.c 21 Sep 2001 04:49:23 -0000 1.24.2.2 +++ keyword.c 25 May 2002 17:15:04 -0000 @@ -32,11 +32,11 @@ */ #ifndef lint +#include <sys/cdefs.h> #if 0 -static char sccsid[] = "@(#)keyword.c 8.5 (Berkeley) 4/2/94"; +__RCSID("@(#)keyword.c 8.5 (Berkeley) 4/2/94"); #else -static const char rcsid[] = - "$FreeBSD: src/bin/ps/keyword.c,v 1.24.2.2 2001/09/21 04:49:23 peter Exp $"; +__FBSDID("$FreeBSD: src/bin/ps/keyword.c,v 1.24.2.2 2001/09/21 04:49:23 peter Exp $"); #endif #endif /* not lint */ @@ -47,6 +47,7 @@ #include <sys/sysctl.h> #include <sys/ucred.h> #include <sys/user.h> +#include <sys/queue.h> #include <err.h> #include <errno.h> @@ -58,8 +59,16 @@ #include "ps.h" -static VAR *findvar __P((char *)); -static int vcmp __P((const void *, const void *)); +#define FMTSEP ", \t\n" + +#if defined(COMPAT_BSD44) +static void bsd_parsefmt1 __P((char *, char *)); +#endif +#if defined(COMPAT_SUSV2) +static void susv2_parsefmt1 __P((char *, char *, char *)); +#endif +static VAR *findvar __P((char *, char *)); +static int vcmp __P((const void *, const void *)); #ifdef NOTINUSE int utime(), stime(), ixrss(), idrss(), isrss(); @@ -83,113 +92,156 @@ #define USERLEN UT_NAMESIZE VAR var[] = { - {"%cpu", "%CPU", NULL, 0, pcpu, NULL, 4}, - {"%mem", "%MEM", NULL, 0, pmem, NULL, 4}, - {"acflag", "ACFLG", - NULL, 0, pvar, NULL, 3, POFF(p_acflag), USHORT, "x"}, - {"acflg", "", "acflag"}, - {"blocked", "", "sigmask"}, - {"caught", "", "sigcatch"}, - {"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16}, - {"cpu", "CPU", NULL, 0, pvar, NULL, 3, POFF(p_estcpu), UINT, "d"}, - {"cputime", "", "time"}, - {"f", "F", NULL, 0, pvar, NULL, 7, POFF(p_flag), INT, "x"}, - {"flags", "", "f"}, - {"ignored", "", "sigignore"}, - {"inblk", "INBLK", - NULL, USER, rvar, NULL, 4, ROFF(ru_inblock), LONG, "ld"}, - {"inblock", "", "inblk"}, - {"jobc", "JOBC", NULL, 0, evar, NULL, 4, EOFF(e_jobc), SHORT, "d"}, - {"ktrace", "KTRACE", - NULL, 0, pvar, NULL, 8, POFF(p_traceflag), INT, "x"}, - {"ktracep", "KTRACEP", - NULL, 0, pvar, NULL, 8, POFF(p_tracep), LONG, "lx"}, - {"lim", "LIM", NULL, 0, maxrss, NULL, 5}, - {"login", "LOGIN", NULL, LJUST, logname, NULL, MAXLOGNAME-1}, - {"logname", "", "login"}, - {"lstart", "STARTED", NULL, LJUST|USER, lstarted, NULL, 28}, - {"majflt", "MAJFLT", - NULL, USER, rvar, NULL, 4, ROFF(ru_majflt), LONG, "ld"}, - {"minflt", "MINFLT", - NULL, USER, rvar, NULL, 4, ROFF(ru_minflt), LONG, "ld"}, - {"msgrcv", "MSGRCV", - NULL, USER, rvar, NULL, 4, ROFF(ru_msgrcv), LONG, "ld"}, - {"msgsnd", "MSGSND", - NULL, USER, rvar, NULL, 4, ROFF(ru_msgsnd), LONG, "ld"}, - {"ni", "", "nice"}, - {"nice", "NI", NULL, 0, pvar, NULL, 2, POFF(p_nice), CHAR, "d"}, - {"nivcsw", "NIVCSW", - NULL, USER, rvar, NULL, 5, ROFF(ru_nivcsw), LONG, "ld"}, - {"nsignals", "", "nsigs"}, - {"nsigs", "NSIGS", - NULL, USER, rvar, NULL, 4, ROFF(ru_nsignals), LONG, "ld"}, - {"nswap", "NSWAP", - NULL, USER, rvar, NULL, 4, ROFF(ru_nswap), LONG, "ld"}, - {"nvcsw", "NVCSW", - NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw), LONG, "ld"}, - {"nwchan", "WCHAN", NULL, 0, pvar, NULL, 8, POFF(p_wchan), KPTR, "lx"}, - {"oublk", "OUBLK", - NULL, USER, rvar, NULL, 4, ROFF(ru_oublock), LONG, "ld"}, - {"oublock", "", "oublk"}, - {"p_ru", "P_RU", NULL, 0, pvar, NULL, 6, POFF(p_ru), KPTR, "lx"}, - {"paddr", "PADDR", NULL, 0, evar, NULL, 8, EOFF(e_paddr), KPTR, "lx"}, - {"pagein", "PAGEIN", NULL, USER, pagein, NULL, 6}, - {"pcpu", "", "%cpu"}, - {"pending", "", "sig"}, - {"pgid", "PGID", - NULL, 0, evar, NULL, PIDLEN, EOFF(e_pgid), UINT, PIDFMT}, - {"pid", "PID", NULL, 0, pvar, NULL, PIDLEN, POFF(p_pid), UINT, PIDFMT}, - {"pmem", "", "%mem"}, - {"ppid", "PPID", - NULL, 0, evar, NULL, PIDLEN, EOFF(e_ppid), UINT, PIDFMT}, - {"pri", "PRI", NULL, 0, pri, NULL, 3}, - {"re", "RE", NULL, 0, pvar, NULL, 3, POFF(p_swtime), UINT, "d"}, - {"rgid", "RGID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_rgid), - UINT, UIDFMT}, - {"rlink", "RLINK", - NULL, 0, pvar, NULL, 8, POFF(p_procq.tqe_prev), KPTR, "lx"}, - {"rss", "RSS", NULL, 0, p_rssize, NULL, 4}, - {"rssize", "", "rsz"}, - {"rsz", "RSZ", NULL, 0, rssize, NULL, 4}, - {"rtprio", "RTPRIO", NULL, 0, rtprior, NULL, 7, POFF(p_rtprio)}, - {"ruid", "RUID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_ruid), - UINT, UIDFMT}, - {"ruser", "RUSER", NULL, LJUST|DSIZ, runame, s_runame, USERLEN}, - {"sess", "SESS", NULL, 0, evar, NULL, 6, EOFF(e_sess), KPTR, "lx"}, - {"sig", "PENDING", NULL, 0, pvar, NULL, 8, POFF(p_siglist), INT, "x"}, - {"sigcatch", "CAUGHT", - NULL, 0, evar, NULL, 8, EOFF(e_procsig.ps_sigcatch), UINT, "x"}, - {"sigignore", "IGNORED", - NULL, 0, evar, NULL, 8, EOFF(e_procsig.ps_sigignore), UINT, "x"}, - {"sigmask", "BLOCKED", - NULL, 0, pvar, NULL, 8, POFF(p_sigmask), UINT, "x"}, - {"sl", "SL", NULL, 0, pvar, NULL, 3, POFF(p_slptime), UINT, "d"}, - {"start", "STARTED", NULL, LJUST|USER, started, NULL, 7}, - {"stat", "", "state"}, - {"state", "STAT", NULL, 0, state, NULL, 4}, - {"svgid", "SVGID", NULL, 0, - evar, NULL, UIDLEN, EOFF(e_pcred.p_svgid), UINT, UIDFMT}, - {"svuid", "SVUID", NULL, 0, - evar, NULL, UIDLEN, EOFF(e_pcred.p_svuid), UINT, UIDFMT}, - {"tdev", "TDEV", NULL, 0, tdev, NULL, 4}, - {"time", "TIME", NULL, USER, cputime, NULL, 9}, - {"tpgid", "TPGID", - NULL, 0, evar, NULL, 4, EOFF(e_tpgid), UINT, PIDFMT}, - {"tsess", "TSESS", NULL, 0, evar, NULL, 6, EOFF(e_tsess), KPTR, "lx"}, - {"tsiz", "TSIZ", NULL, 0, tsize, NULL, 4}, - {"tt", "TT ", NULL, 0, tname, NULL, 4}, - {"tty", "TTY", NULL, LJUST, longtname, NULL, 8}, - {"ucomm", "UCOMM", NULL, LJUST, ucomm, NULL, MAXCOMLEN}, - {"uid", "UID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_ucred.cr_uid), - UINT, UIDFMT}, - {"upr", "UPR", NULL, 0, pvar, NULL, 3, POFF(p_usrpri), CHAR, "d"}, - {"user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN}, - {"usrpri", "", "upr"}, - {"vsize", "", "vsz"}, - {"vsz", "VSZ", NULL, 0, vsize, NULL, 5}, - {"wchan", "WCHAN", NULL, LJUST, wchan, NULL, 6}, - {"xstat", "XSTAT", NULL, 0, pvar, NULL, 4, POFF(p_xstat), USHORT, "x"}, - {""}, + { "%cpu", "%CPU", NULL, 0, pcpu, NULL, 4 }, + { "%mem", "%MEM", NULL, 0, pmem, NULL, 4 }, + { "acflag", "ACFLG", NULL, + 0, pvar, NULL, 3, POFF(p_acflag), USHORT, "x" }, + { "acflg", NULL, "acflag" }, +#if defined(COMPAT_SUSV2) + { "addr", "ADDR", "paddr" }, + { "args", NULL, "command" }, +#endif + { "blocked", NULL, "sigmask" }, +#if defined(COMPAT_SUSV2) + { "c", "C", NULL, 0, pvar, NULL, 1, POFF(p_oncpu), UCHAR, "d" }, +#endif + { "caught", NULL, "sigcatch" }, +#if defined(COMPAT_SUSV2) + { "comm", "COMMAND", "ucomm" }, +#endif + { "command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16 }, + { "cpu", "CPU", NULL, 0, pvar, NULL, 3, POFF(p_estcpu), UINT, "d" }, + { "cputime", NULL, "time" }, +#if defined(COMPAT_SUSV2) + { "etime", "ELAPSED", NULL, USER, etime, NULL, 11 }, +#endif + { "f", "F", NULL, 0, pvar, NULL, 7, POFF(p_flag), INT, "x" }, + { "flags", NULL, "f" }, +#if defined(COMPAT_SUSV2) + { "group", "GROUP", NULL, LJUST|DSIZ, gname, s_gname, USERLEN }, +#endif + { "ignored", NULL, "sigignore" }, + { "inblk", "INBLK", NULL, + USER, rvar, NULL, 4, ROFF(ru_inblock), LONG, "ld" }, + { "inblock", NULL, "inblk" }, + { "jobc", "JOBC", NULL, 0, evar, NULL, 4, EOFF(e_jobc), SHORT, "d" }, + { "ktrace", "KTRACE", NULL, + 0, pvar, NULL, 8, POFF(p_traceflag), INT, "x" }, + { "ktracep", "KTRACEP", NULL, + 0, pvar, NULL, 8, POFF(p_tracep), LONG, "lx" }, +#if defined(COMPAT_SUSV2) + { "l", "L", "state" }, +#endif + { "lim", "LIM", NULL, 0, maxrss, NULL, 5 }, + { "login", "LOGIN", NULL, LJUST, logname, NULL, MAXLOGNAME-1 }, + { "logname", NULL, "login" }, + { "lstart", "STARTED", NULL, LJUST|USER, lstarted, NULL, 28 }, + { "majflt", "MAJFLT", NULL, + USER, rvar, NULL, 7, ROFF(ru_majflt), LONG, "ld" }, + { "minflt", "MINFLT", NULL, + USER, rvar, NULL, 7, ROFF(ru_minflt), LONG, "ld" }, + { "msgrcv", "MSGRCV", NULL, + USER, rvar, NULL, 7, ROFF(ru_msgrcv), LONG, "ld" }, + { "msgsnd", "MSGSND", NULL, + USER, rvar, NULL, 7, ROFF(ru_msgsnd), LONG, "ld" }, + { "ni", NULL, "nice" }, +/* SUSV2 */ + { "nice", "NI", NULL, 0, pvar, NULL, 3, POFF(p_nice), CHAR, "d" }, + { "nivcsw", "NIVCSW", NULL, + USER, rvar, NULL, 5, ROFF(ru_nivcsw), LONG, "ld" }, + { "nsignals", NULL, "nsigs" }, + { "nsigs", "NSIGS", NULL, + USER, rvar, NULL, 4, ROFF(ru_nsignals), LONG, "ld" }, + { "nswap", "NSWAP", NULL, + USER, rvar, NULL, 4, ROFF(ru_nswap), LONG, "ld" }, + { "nvcsw", "NVCSW", NULL, + USER, rvar, NULL, 5, ROFF(ru_nvcsw), LONG, "ld" }, + { "nwchan", "WCHAN", NULL, + 0, pvar, NULL, 8, POFF(p_wchan), KPTR, "lx" }, + { "oublk", "OUBLK", NULL, + USER, rvar, NULL, 6, ROFF(ru_oublock), LONG, "ld" }, + { "oublock", NULL, "oublk" }, + { "p_ru", "P_RU", NULL, 0, pvar, NULL, 6, POFF(p_ru), KPTR, "lx" }, + { "paddr", "PADDR", NULL, + 0, evar, NULL, 8, EOFF(e_paddr), KPTR, "lx" }, + { "pagein", "PAGEIN", NULL, USER, pagein, NULL, 6 }, +/* SUSV2 */ + { "pcpu", NULL, "%cpu" }, + { "pending", NULL, "sig" }, +/* SUSV2 */ + { "pgid", "PGID", NULL, + 0, evar, NULL, PIDLEN, EOFF(e_pgid), UINT, PIDFMT }, +/* SUSV2 */ + { "pid", "PID", NULL, + 0, pvar, NULL, PIDLEN, POFF(p_pid), UINT, PIDFMT }, + { "pmem", NULL, "%mem" }, +/* SUSV2 */ + { "ppid", "PPID", NULL, + 0, evar, NULL, PIDLEN, EOFF(e_ppid), UINT, PIDFMT }, + { "pri", "PRI", NULL, 0, pri, NULL, 3 }, + { "re", "RE", NULL, 0, pvar, NULL, 6, POFF(p_swtime), UINT, "d" }, + { "rgid", "RGID", NULL, + 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_rgid), UINT, UIDFMT }, +#if defined(COMPAT_SUSV2) + { "rgroup", "RGROUP", NULL, LJUST|DSIZ, rgname, s_rgname, USERLEN }, +#endif + { "rlink", "RLINK", NULL, + 0, pvar, NULL, 8, POFF(p_procq.tqe_prev), KPTR, "lx" }, + { "rss", "RSS", NULL, 0, p_rssize, NULL, 5 }, + { "rssize", NULL, "rsz" }, + { "rsz", "RSZ", NULL, 0, rssize, NULL, 5 }, + { "rtprio", "RTPRIO", NULL, 0, rtprior, NULL, 7, POFF(p_rtprio) }, + { "ruid", "RUID", NULL, + 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_ruid), UINT, UIDFMT }, +/* SUSV2 */ + { "ruser", "RUSER", NULL, LJUST|DSIZ, runame, s_runame, USERLEN }, + { "s", "S", "state" }, + { "sess", "SESS", NULL, 0, evar, NULL, 7, EOFF(e_sess), KPTR, "lx" }, +/* SVR4 { "sid", "SID", "sess" }, */ + { "sig", "PENDING", NULL, + 0, pvar, NULL, 8, POFF(p_siglist), INT, "x" }, + { "sigcatch", "CAUGHT", NULL, + 0, evar, NULL, 8, EOFF(e_procsig.ps_sigcatch), UINT, "x" }, + { "sigignore", "IGNORED", NULL, + 0, evar, NULL, 8, EOFF(e_procsig.ps_sigignore), UINT, "x" }, + { "sigmask", "BLOCKED", NULL, + 0, pvar, NULL, 8, POFF(p_sigmask), UINT, "x" }, + { "sl", "SL", NULL, 0, pvar, NULL, 6, POFF(p_slptime), UINT, "d" }, + { "start", "STARTED", NULL, LJUST|USER, started, NULL, 7 }, + { "stat", NULL, "state" }, + { "state", "STAT", NULL, 0, state, NULL, 4 }, +#if defined(COMPAT_SUSV2) + { "stime", "STIME", NULL, USER, stime, NULL, 8 }, +#endif + { "svgid", "SVGID", NULL, + 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_svgid), UINT, UIDFMT }, + { "svuid", "SVUID", NULL, + 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_svuid), UINT, UIDFMT }, + { "tdev", "TDEV", NULL, 0, tdev, NULL, 4 }, +/* SUSV2 */ + { "time", "TIME", NULL, USER, cputime, NULL, 9 }, + { "tpgid", "TPGID", NULL, + 0, evar, NULL, 6, EOFF(e_tpgid), UINT, PIDFMT }, + { "tsess", "TSESS", NULL, + 0, evar, NULL, 7, EOFF(e_tsess), KPTR, "lx" }, + { "tsiz", "TSIZ", NULL, 0, tsize, NULL, 5 }, + { "tt", "TT ", NULL, 0, tname, NULL, 4 }, +/* SUSV2 */ + { "tty", "TTY", NULL, LJUST, longtname, NULL, 8 }, + { "ucomm", "UCOMM", NULL, LJUST, ucomm, NULL, MAXCOMLEN }, + { "uid", "UID", NULL, + 0, evar, NULL, UIDLEN, EOFF(e_ucred.cr_uid), UINT, UIDFMT }, + { "upr", "UPR", NULL, 0, pvar, NULL, 3, POFF(p_usrpri), CHAR, "d" }, +/* SUSV2 */ + { "user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN }, + { "usrpri", NULL, "upr" }, + { "vsize", NULL, "vsz" }, +/* SUSV2 */ + { "vsz", "VSZ", NULL, 0, vsize, NULL, 5 }, + { "wchan", "WCHAN", NULL, LJUST, wchan, NULL, 7 }, + { "xstat", "XSTAT", NULL, + 0, pvar, NULL, 4, POFF(p_xstat), USHORT, "x" }, + { "" }, }; void @@ -213,65 +265,128 @@ (void) printf("\n"); } +#if defined(COMPAT_BSD44) void -parsefmt(p) +bsd_parsefmt(p) char *p; { - static struct varent *vtail; + bsd_parsefmt1(p, NULL); +} -#define FMTSEP " \t,\n" - while (p && *p) { - char *cp; - VAR *v; - struct varent *vent; +static void +bsd_parsefmt1(p, h) + char *p, *h; +{ + char *cp, *hp; + VAR *v; + VARENT *vent; + while (p && *p) { while ((cp = strsep(&p, FMTSEP)) != NULL && *cp == '\0') /* void */; - if (cp == NULL || !(v = findvar(cp))) + if ((hp = strchr(cp, '=')) != NULL) + *hp++ = '\0'; + if (cp == NULL || !(v = findvar(cp, hp ? hp : h))) continue; - if ((vent = malloc(sizeof(struct varent))) == NULL) + if ((vent = malloc(sizeof(VARENT))) == NULL) err(1, NULL); vent->var = v; - vent->next = NULL; - if (vhead == NULL) - vhead = vtail = vent; - else { - vtail->next = vent; - vtail = vent; + STAILQ_INSERT_TAIL(&varlist, vent, list); + } + if (STAILQ_EMPTY(&varlist)) + errx(1, "no valid keywords"); +} +#endif + +#if defined(COMPAT_SUSV2) +void +susv2_parsefmt(p, f) + char *p, *f; +{ + susv2_parsefmt1(p, f, NULL); +} + +static void +susv2_parsefmt1(p, f, h) + char *p, *f, *h; +{ + char *cp, *hp; + VAR *v; + VARENT *vent; +loop: + while (p && *p) { + while ((cp = strsep(&p, FMTSEP)) != NULL && *cp == '\0') + /* void */; + if (cp == NULL) + continue; + if ((hp = strpbrk(cp, "[=")) != NULL) { + switch (*hp) { + case '[': + if (!f || !*f || strpbrk(hp, f)) + *hp++ = '\0'; + else + continue; + if (!(hp = strchr(hp, '='))) + break; + /* FALLTHROUGH */ + case '=': + *hp++ = '\0'; + } } + if (!(v = findvar(cp, hp ? hp : h))) + continue; + STAILQ_FOREACH(vent, &varlist, list) + if (!strcmp(v->name, vent->var->name)) { + free(v); + goto loop; + } + if ((vent = malloc(sizeof(VARENT))) == NULL) + err(1, NULL); + vent->var = v; + STAILQ_INSERT_TAIL(&varlist, vent, list); } - if (!vhead) + if (STAILQ_EMPTY(&varlist)) errx(1, "no valid keywords"); } +#endif static VAR * -findvar(p) - char *p; +findvar(p, h) + char *p, *h; { VAR *v, key; - char *hp; - int vcmp(); - - 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) { +#if defined(COMPAT_BSD44) + if (h) { + h = NULL; warnx("%s: illegal keyword specification", p); eval = 1; } - parsefmt(v->alias); +#endif +#if defined(COMPAT_SUSV2) + susv2_parsefmt1(v->alias, NULL, h ? h : v->header); +#else + bsd_parsefmt1(v->alias, h ? h : v->header); +#endif return ((VAR *)NULL); } if (!v) { warnx("%s: keyword not found", p); eval = 1; - } else if (hp) - v->header = hp; + } else if (h) { + VAR *vp; + + if ((vp = malloc(sizeof(VAR))) == NULL) + err(1, NULL); + memcpy(vp, v, sizeof(VAR)); + v = vp; + if ((v->header = strdup(h)) == NULL) + err(1, NULL); + } return (v); } Index: nlist.c =================================================================== RCS file: /home/ncvs/src/bin/ps/nlist.c,v retrieving revision 1.12.6.2 diff -u -r1.12.6.2 nlist.c --- nlist.c 1 Aug 2001 05:04:48 -0000 1.12.6.2 +++ nlist.c 25 May 2002 17:12:30 -0000 @@ -32,11 +32,11 @@ */ #ifndef lint +#include <sys/cdefs.h> #if 0 -static char sccsid[] = "@(#)nlist.c 8.4 (Berkeley) 4/2/94"; +__RCSID("@(#)nlist.c 8.4 (Berkeley) 4/2/94"); #endif -static const char rcsid[] = - "$FreeBSD: src/bin/ps/nlist.c,v 1.12.6.2 2001/08/01 05:04:48 obrien Exp $"; +__FBSDID("$FreeBSD: src/bin/ps/nlist.c,v 1.12.6.2 2001/08/01 05:04:48 obrien Exp $"); #endif /* not lint */ #include <sys/types.h> Index: print.c =================================================================== RCS file: /home/ncvs/src/bin/ps/print.c,v retrieving revision 1.36.2.3 diff -u -r1.36.2.3 print.c --- print.c 12 Mar 2002 18:12:57 -0000 1.36.2.3 +++ print.c 25 May 2002 17:18:09 -0000 @@ -32,11 +32,11 @@ */ #ifndef lint +#include <sys/cdefs.h> #if 0 -static char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94"; +__RCSID("@(#)print.c 8.6 (Berkeley) 4/16/94"); #endif -static const char rcsid[] = - "$FreeBSD: src/bin/ps/print.c,v 1.36.2.3 2002/03/12 18:12:57 phantom Exp $"; +__FBSDID("$FreeBSD: src/bin/ps/print.c,v 1.36.2.3 2002/03/12 18:12:57 phantom Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -44,10 +44,10 @@ #include <sys/resource.h> #include <sys/proc.h> #include <sys/stat.h> - #include <sys/ucred.h> #include <sys/user.h> #include <sys/sysctl.h> +#include <sys/queue.h> #include <vm/vm.h> #include <err.h> @@ -64,22 +64,44 @@ #include "ps.h" +#define FMTLEN 64 +#define BUFLEN 128 + +static const char sfmt[] = "%s"; +static const char wsfmt[] = "%*s"; +static const char wwsfmt[] = "%*.*s"; +static const char lwsfmt[] = "%-*s"; +static const char lwwsfmt[] = "%-*.*s"; +static const char wdfmt[] = "%*d"; +static const char wldfmt[] = "%*ld"; +static const char wlufmt[] = "%*lu"; +static const char wffmt[] = "%*.1f"; + +static void gettime __P((time_t *, struct timeval *)); +static double getpmem __P((KINFO *)); +static void printval __P((char *, VAR *v)); + void printheader() { VAR *v; - struct varent *vent; + VARENT *vent; - for (vent = vhead; vent; vent = vent->next) { + STAILQ_FOREACH(vent, &varlist, list) + if (*vent->var->header) + break; + if (!vent) + return; + STAILQ_FOREACH(vent, &varlist, list) { v = vent->var; if (v->flag & LJUST) { - if (vent->next == NULL) /* last one */ - (void)printf("%s", v->header); + if (STAILQ_NEXT(vent, list) == NULL) /* last one */ + (void)printf(sfmt, v->header); else - (void)printf("%-*s", v->width, v->header); + (void)printf(lwsfmt, v->width, v->header); } else - (void)printf("%*s", v->width, v->header); - if (vent->next != NULL) + (void)printf(wsfmt, v->width, v->header); + if (STAILQ_NEXT(vent, list) != NULL) (void)putchar(' '); } (void)putchar('\n'); @@ -97,10 +119,10 @@ v = ve->var; if (cflag) { - if (ve->next == NULL) /* last field, don't pad */ - (void)printf("%s", KI_PROC(k)->p_comm); + if (STAILQ_NEXT(ve, list) == NULL) /* last field, don't pad */ + (void)printf(sfmt, KI_PROC(k)->p_comm); else - (void)printf("%-*s", v->width, KI_PROC(k)->p_comm); + (void)printf(lwsfmt, v->width, KI_PROC(k)->p_comm); return; } @@ -114,12 +136,13 @@ } else vis_env = NULL; - if (ve->next == NULL) { - /* last field */ + if (STAILQ_NEXT(ve, list) == NULL) { /* last field */ if (termwidth == UNLIMITED) { - if (vis_env) - (void)printf("%s ", vis_env); - (void)printf("%s", vis_args); + if (vis_env) { + (void)printf(sfmt, vis_env); + (void)putchar(' '); + } + (void)printf(sfmt, vis_args); } else { left = termwidth - (totwidth - v->width); if (left < 1) /* already wrapped, just use std width */ @@ -128,14 +151,14 @@ while (--left >= 0 && *cp) (void)putchar(*cp++); if (--left >= 0) - putchar(' '); + (void)putchar(' '); } for (cp = vis_args; --left >= 0 && *cp != '\0';) (void)putchar(*cp++); } } else /* XXX env? */ - (void)printf("%-*.*s", v->width, v->width, vis_args); + (void)printf(lwwsfmt, v->width, v->width, vis_args); free(vis_args); if (vis_env != NULL) free(vis_env); @@ -149,7 +172,7 @@ VAR *v; v = ve->var; - (void)printf("%-*s", v->width, KI_PROC(k)->p_comm); + (void)printf(lwsfmt, v->width, KI_PROC(k)->p_comm); } void @@ -161,7 +184,8 @@ char *s; v = ve->var; - (void)printf("%-*s", v->width, (s = KI_EPROC(k)->e_login, *s) ? s : "-"); + (void)printf(lwsfmt, v->width, + (s = KI_EPROC(k)->e_login, *s) ? s : "-"); } void @@ -173,7 +197,7 @@ int flag; char *cp; VAR *v; - char buf[16]; + char buf[BUFLEN]; v = ve->var; p = KI_PROC(k); @@ -183,29 +207,28 @@ switch (p->p_stat) { case SSTOP: - *cp = 'T'; + *cp++ = 'T'; break; case SSLEEP: if (flag & P_SINTR) /* interruptable (long) */ - *cp = p->p_slptime >= MAXSLP ? 'I' : 'S'; + *cp++ = p->p_slptime >= MAXSLP ? 'I' : 'S'; else - *cp = 'D'; + *cp++ = 'D'; break; case SRUN: case SIDL: - *cp = 'R'; + *cp++ = 'R'; break; case SZOMB: - *cp = 'Z'; + *cp++ = 'Z'; break; default: - *cp = '?'; + *cp++ = '?'; } - cp++; if (!(flag & P_INMEM)) *cp++ = 'W'; if (p->p_nice < NZERO) @@ -222,12 +245,13 @@ *cp++ = 'L'; if (KI_EPROC(k)->e_flag & EPROC_SLEADER) *cp++ = 's'; - if ((flag & P_CONTROLT) && KI_EPROC(k)->e_pgid == KI_EPROC(k)->e_tpgid) + if ((flag & P_CONTROLT) && + KI_EPROC(k)->e_pgid == KI_EPROC(k)->e_tpgid) *cp++ = '+'; if (flag & P_JAILED) *cp++ = 'J'; *cp = '\0'; - (void)printf("%-*s", v->width, buf); + (void)printf(lwsfmt, v->width, buf); } void @@ -238,7 +262,12 @@ VAR *v; v = ve->var; - (void)printf("%*d", v->width, KI_PROC(k)->p_priority - PZERO); +#if defined(COMPAT_SUSV2) + if (susv2) + (void)printf(wdfmt, v->width, KI_PROC(k)->p_priority); + else +#endif + (void)printf(wdfmt, v->width, KI_PROC(k)->p_priority - PZERO); } void @@ -249,8 +278,8 @@ VAR *v; v = ve->var; - (void)printf("%-*s", - (int)v->width, user_from_uid(KI_EPROC(k)->e_ucred.cr_uid, 0)); + (void)printf(lwsfmt, v->width, + user_from_uid(KI_EPROC(k)->e_ucred.cr_uid, 0)); } int @@ -268,17 +297,57 @@ VAR *v; v = ve->var; - (void)printf("%-*s", - (int)v->width, user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0)); + (void)printf(lwsfmt, v->width, + user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0)); } int s_runame(k) KINFO *k; { - return (strlen(user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0))); + return (strlen(user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0))); } +#if defined(COMPAT_SUSV2) +void +gname(k, ve) + KINFO *k; + VARENT *ve; +{ + VAR *v; + + v = ve->var; + (void)printf(lwsfmt, v->width, + group_from_gid(KI_EPROC(k)->e_ucred.cr_gid, 0)); +} + +int +s_gname(k) + KINFO *k; +{ + return (strlen(group_from_gid(KI_EPROC(k)->e_ucred.cr_gid, 0))); +} + +void +rgname(k, ve) + KINFO *k; + VARENT *ve; +{ + VAR *v; + + v = ve->var; + (void)printf(lwsfmt, v->width, + group_from_gid(KI_EPROC(k)->e_pcred.p_rgid, 0)); +} + +int +s_rgname(k) + KINFO *k; +{ + return (strlen(group_from_gid(KI_EPROC(k)->e_pcred.p_rgid, 0))); +} +#endif + void tdev(k, ve) KINFO *k; @@ -286,16 +355,16 @@ { VAR *v; dev_t dev; - char buff[16]; + char buf[BUFLEN]; v = ve->var; dev = KI_EPROC(k)->e_tdev; if (dev == NODEV) - (void)printf("%*s", v->width, "??"); + (void)printf(wsfmt, v->width, "??"); else { - (void)snprintf(buff, sizeof(buff), + (void)snprintf(buf, sizeof(buf), "%d/%d", major(dev), minor(dev)); - (void)printf("%*s", v->width, buff); + (void)printf(wsfmt, v->width, buf); } } @@ -311,13 +380,13 @@ v = ve->var; dev = KI_EPROC(k)->e_tdev; if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) - (void)printf("%*s ", v->width-1, "??"); + (void)printf(wsfmt, v->width, "?? "); 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, - KI_EPROC(k)->e_flag & EPROC_CTTY ? ' ' : '-'); + (void)printf(wwsfmt, v->width-1, v->width-1, ttname); + (void)putchar(KI_EPROC(k)->e_flag & EPROC_CTTY ? ' ' : '-'); } } @@ -333,9 +402,27 @@ v = ve->var; dev = KI_EPROC(k)->e_tdev; if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) - (void)printf("%-*s", v->width, "??"); + (void)printf(lwsfmt, v->width, "??"); else - (void)printf("%-*s", v->width, ttname); + (void)printf(lwsfmt, v->width, ttname); +} + +static void +gettime(tp, tvp) + time_t *tp; + struct timeval *tvp; +{ + static time_t t; + static struct timeval tv; + + if (!t) { + (void)time(&t); + (void)gettimeofday(&tv, NULL); + } + if (tp) + *tp = t; + if (tvp) + *tvp = tv; } void @@ -344,15 +431,15 @@ VARENT *ve; { VAR *v; - static time_t now; + time_t now; time_t then; struct tm *tp; - char buf[100]; + char buf[BUFLEN]; static int use_ampm = -1; v = ve->var; if (!k->ki_u.u_valid) { - (void)printf("%-*s", v->width, "-"); + (void)printf(lwsfmt, v->width, "-"); return; } @@ -361,18 +448,48 @@ then = k->ki_u.u_start.tv_sec; tp = localtime(&then); - if (!now) - (void)time(&now); + gettime(&now, NULL); if (now - k->ki_u.u_start.tv_sec < 24 * 3600) { (void)strftime(buf, sizeof(buf) - 1, use_ampm ? "%l:%M%p" : "%k:%M ", tp); } else if (now - k->ki_u.u_start.tv_sec < 7 * 86400) { (void)strftime(buf, sizeof(buf) - 1, use_ampm ? "%a%I%p" : "%a%H ", tp); - } else - (void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp); - (void)printf("%-*s", v->width, buf); + } else { + static const char fmt[] = "%e%b%y"; /* avoid gcc warning */ + (void)strftime(buf, sizeof(buf) - 1, fmt, tp); + } + (void)printf(lwsfmt, v->width, buf); +} + +#if defined(COMPAT_SUSV2) +void +stime(k, ve) + KINFO *k; + VARENT *ve; +{ + VAR *v; + time_t now; + time_t then; + struct tm *tp; + char buf[BUFLEN]; + + v = ve->var; + if (!k->ki_u.u_valid) { + (void)printf(lwsfmt, v->width, "-"); + return; + } + + then = k->ki_u.u_start.tv_sec; + tp = localtime(&then); + gettime(&now, NULL); + if (now - k->ki_u.u_start.tv_sec < 24 * 3600) + (void)strftime(buf, sizeof(buf) - 1, "%T", tp); + else + (void)strftime(buf, sizeof(buf) - 1, "%b %d", tp); + (void)printf(wsfmt, v->width, buf); } +#endif void lstarted(k, ve) @@ -381,16 +498,17 @@ { VAR *v; time_t then; - char buf[100]; + char buf[BUFLEN]; + static const char fmt[] = "%c"; /* avoid gcc warning */ v = ve->var; if (!k->ki_u.u_valid) { - (void)printf("%-*s", v->width, "-"); + (void)printf(lwsfmt, v->width, "-"); return; } then = k->ki_u.u_start.tv_sec; - (void)strftime(buf, sizeof(buf) -1, "%c", localtime(&then)); - (void)printf("%-*s", v->width, buf); + (void)strftime(buf, sizeof(buf) -1, fmt, localtime(&then)); + (void)printf(lwsfmt, v->width, buf); } void @@ -403,13 +521,13 @@ v = ve->var; if (KI_PROC(k)->p_wchan) { if (KI_PROC(k)->p_wmesg) - (void)printf("%-*.*s", v->width, v->width, + (void)printf(lwwsfmt, v->width, v->width, KI_EPROC(k)->e_wmesg); else (void)printf("%-*lx", v->width, (long)KI_PROC(k)->p_wchan); } else - (void)printf("%-*s", v->width, "-"); + (void)printf(lwsfmt, v->width, "-"); } #ifndef pgtok @@ -424,7 +542,7 @@ VAR *v; v = ve->var; - (void)printf("%*d", v->width, + (void)printf(wdfmt, v->width, (KI_EPROC(k)->e_vm.vm_map.size/1024)); } @@ -437,7 +555,7 @@ v = ve->var; /* XXX don't have info about shared */ - (void)printf("%*lu", v->width, + (void)printf(wlufmt, v->width, (u_long)pgtok(KI_EPROC(k)->e_vm.vm_rssize)); } @@ -449,7 +567,8 @@ VAR *v; v = ve->var; - (void)printf("%*ld", v->width, (long)pgtok(KI_EPROC(k)->e_vm.vm_rssize)); + (void)printf(wldfmt, v->width, + (long)pgtok(KI_EPROC(k)->e_vm.vm_rssize)); } void @@ -460,11 +579,14 @@ VAR *v; long secs; long psecs; /* "parts" of a second. first micro, then centi */ - char obuff[128]; + long mins, hours, days; + char fmt[FMTLEN]; + char buf[BUFLEN]; static char decimal_point = 0; if (!decimal_point) decimal_point = localeconv()->decimal_point[0]; + v = ve->var; if (KI_PROC(k)->p_stat == SZOMB || !k->ki_u.u_valid) { secs = 0; @@ -481,7 +603,7 @@ secs += k->ki_u.u_cru.ru_utime.tv_sec + k->ki_u.u_cru.ru_stime.tv_sec; psecs += k->ki_u.u_cru.ru_utime.tv_usec + - k->ki_u.u_cru.ru_stime.tv_usec; + k->ki_u.u_cru.ru_stime.tv_usec; } /* * round and scale to 100's @@ -490,10 +612,75 @@ 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); + mins = secs / 60; + *fmt = '\0'; +#if defined(COMPAT_SUSV2) + if (susv2) { + hours = mins / 60; + days = hours / 24; + hours %= 24; + mins %= 60; + if (days) + strcat(fmt, "%6$02ld-"); + strcat(fmt, "%5$02ld:%1$02ld:%2$02ld"); + } else +#endif + { + hours = days = 0; + strcat(fmt, "%3ld:%02ld%c%02ld"); + } + secs %= 60; + (void)snprintf(buf, sizeof(buf), fmt, + mins, secs, decimal_point, psecs, hours, days); + (void)printf(wsfmt, v->width, buf); +} + +#if defined(COMPAT_SUSV2) +void +etime +(k, ve) + KINFO *k; + VARENT *ve; +{ + VAR *v; + struct timeval now; + long psecs, secs, mins, hours, days; + char fmt[FMTLEN]; + char buf[BUFLEN]; + + v = ve->var; + if (!k->ki_u.u_valid) { + (void)printf(wsfmt, v->width, "-"); + return; + } + gettime(NULL, &now); + secs = now.tv_sec - k->ki_u.u_start.tv_sec; + psecs = now.tv_usec - k->ki_u.u_start.tv_usec; + if (psecs < 0) + secs--, psecs += 1000000; + mins = secs / 60; + *fmt = '\0'; +#if defined(COMPAT_SUSV2) + if (susv2) { + hours = mins / 60; + days = hours / 24; + hours %= 24; + mins %= 60; + if (days) + strcat(fmt, "%5$02ld-"); + if (hours) + strcat(fmt, "%4$02ld:"); + strcat(fmt, "%1$02ld:%2$02ld"); + } else +#endif + strcat(fmt, "%3ld:%02ld.%02ld"); + secs %= 60; + (void)snprintf(buf, sizeof(buf), fmt, mins, secs, psecs, hours, days); + (void)printf(wsfmt, v->width, buf); } +#endif + +#define fxtofl(fixpt) ((double)(fixpt) / fscale) double getpcpu(k) @@ -508,7 +695,6 @@ return (0.0); p = KI_PROC(k); -#define fxtofl(fixpt) ((double)(fixpt) / fscale) /* XXX - I don't like this */ if (p->p_swtime == 0 || (p->p_flag & P_INMEM) == 0) @@ -527,10 +713,10 @@ VAR *v; v = ve->var; - (void)printf("%*.1f", v->width, getpcpu(k)); + (void)printf(wffmt, v->width, getpcpu(k)); } -double +static double getpmem(k) KINFO *k; { @@ -564,7 +750,7 @@ VAR *v; v = ve->var; - (void)printf("%*.1f", v->width, getpmem(k)); + (void)printf(wffmt, v->width, getpmem(k)); } void @@ -575,7 +761,7 @@ VAR *v; v = ve->var; - (void)printf("%*ld", v->width, + (void)printf(wldfmt, v->width, k->ki_u.u_valid ? k->ki_u.u_ru.ru_majflt : 0); } @@ -588,7 +774,7 @@ v = ve->var; /* XXX not yet */ - (void)printf("%*s", v->width, "-"); + (void)printf(wsfmt, v->width, "-"); } void @@ -599,7 +785,8 @@ VAR *v; v = ve->var; - (void)printf("%*ld", v->width, (long)pgtok(KI_EPROC(k)->e_vm.vm_tsize)); + (void)printf(wldfmt, v->width, + (long)pgtok(KI_EPROC(k)->e_vm.vm_tsize)); } void @@ -609,7 +796,7 @@ { VAR *v; struct rtprio *prtp; - char str[8]; + char buf[BUFLEN]; unsigned prio, type; v = ve->var; @@ -618,20 +805,20 @@ type = prtp->type; switch (type) { case RTP_PRIO_REALTIME: - snprintf(str, sizeof(str), "real:%u", prio); + snprintf(buf, sizeof(buf), "real:%u", prio); break; case RTP_PRIO_NORMAL: - strncpy(str, "normal", sizeof(str)); + strncpy(buf, "normal", sizeof(buf)); break; case RTP_PRIO_IDLE: - snprintf(str, sizeof(str), "idle:%u", prio); + snprintf(buf, sizeof(buf), "idle:%u", prio); break; default: - snprintf(str, sizeof(str), "%u:%u", type, prio); + snprintf(buf, sizeof(buf), "%u:%u", type, prio); break; } - str[sizeof(str) - 1] = '\0'; - (void)printf("%*s", v->width, str); + buf[sizeof(buf) - 1] = '\0'; + (void)printf(wsfmt, v->width, buf); } /* @@ -643,7 +830,7 @@ char *bp; VAR *v; { - static char ofmt[32] = "%"; + static char ofmt[FMTLEN] = "%"; char *fcp, *cp; cp = ofmt + 1; @@ -719,7 +906,7 @@ if (k->ki_u.u_valid) printval((char *)((char *)&k->ki_u + v->off), v); else - (void)printf("%*s", v->width, "-"); + (void)printf(wsfmt, v->width, "-"); } void @@ -733,5 +920,5 @@ if (k->ki_u.u_valid) printval((char *)((char *)(&k->ki_u.u_ru) + v->off), v); else - (void)printf("%*s", v->width, "-"); + (void)printf(wsfmt, v->width, "-"); } Index: ps.c =================================================================== RCS file: /home/ncvs/src/bin/ps/ps.c,v retrieving revision 1.30.2.5 diff -u -r1.30.2.5 ps.c --- ps.c 1 Feb 2002 14:09:30 -0000 1.30.2.5 +++ ps.c 11 Jun 2002 02:30:49 -0000 @@ -32,17 +32,13 @@ */ #ifndef lint -static char const copyright[] = -"@(#) Copyright (c) 1990, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 1990, 1993, 1994\\n\ + The Regents of the University of California. All rights reserved.\\n"); #if 0 -static char sccsid[] = "@(#)ps.c 8.4 (Berkeley) 4/2/94"; +__RCSID("@(#)ps.c 8.4 (Berkeley) 4/2/94"); #endif -static const char rcsid[] = - "$FreeBSD: src/bin/ps/ps.c,v 1.30.2.5 2002/02/01 14:09:30 ru Exp $"; +__FBSDID("$FreeBSD: src/bin/ps/ps.c,v 1.30.2.5 2002/02/01 14:09:30 ru Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -52,6 +48,7 @@ #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/sysctl.h> +#include <sys/queue.h> #include <ctype.h> #include <err.h> @@ -66,67 +63,125 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#if defined(COMPAT_SUSV2) +#include <grp.h> +#endif #include <pwd.h> #include <utmp.h> #include "ps.h" -#define SEP ", \t" /* username separators */ +#define SEP ", \t" /* username separators */ +#define BUCKETS 32 /* power of 2 */ +#define SUSV2ENV "SUSV2" /* getenv() */ +#define OPTLEN 64 +#define UIDLEN 32 + +enum entry { + DEV, UID, PID +#if defined(COMPAT_SUSV2) + , FMT, GID, PGID, CMD +#endif +}; + +enum sort { + DEFAULT, SORTMEM, SORTCPU +}; + +/* + * Global variables + */ KINFO *kinfo; -struct varent *vhead, *vtail; +VARLIST varlist = STAILQ_HEAD_INITIALIZER(varlist); -int eval; /* exit value */ -int cflag; /* -c */ -int rawcpu; /* -C */ -int sumrusage; /* -S */ -int termwidth; /* width of screen (0 == infinity) */ +int eval; /* exit value */ +int rawcpu; /* -C */ +int cflag; /* -c */ +int sumrusage; /* -S */ +int termwidth; /* -w : width of screen (0 == infinity) */ int totwidth; /* calculated width of requested variables */ -static int needuser, needcomm, needenv; +#if defined(COMPAT_SUSV2) +int susv2; /* atoi(getenv("SUSV2")) != 0 */ +#endif + +/* + * Local variables + */ + + /* bsd options | susv2 options */ +static int all; /* -a | -a, -d, or -e */ +#if defined(COMPAT_SUSV2) +static char **cmds; /* nop | -C */ +static int ncmds; /* ditto */ +#endif +static int needenv; /* -e */ #if defined(LAZY_PS) -static int forceuread=0; +static int forceuread; /* -f | nop */ #else -static int forceuread=1; +static int forceuread = 1; /* ditto */ #endif +#if defined(COMPAT_SUSV2) +static pid_t *pgids; /* nop | -g */ +static int npgids; /* ditto */ +#endif +static int prtheader; /* -h */ +static char *memf = _PATH_DEVNULL; /* -M | -m */ +static enum sort sortby = DEFAULT; /* -m | -r */ +static char *nlistf = _PATH_DEVNULL; /* -N | -n */ +static pid_t *pids; /* -p | -p */ +static int npids; /* ditto */ +static dev_t *devs; /* -T or -t | -t */ +static int ndevs; /* ditto */ +static uid_t *uids; /* -U | -u */ +static int nuids; /* ditto */ +#if defined(COMPAT_SUSV2) +static uid_t *ruids; /* nop | -U */ +static int nruids; /* ditto */ +static gid_t *gids; /* nop | -G */ +static int ngids; /* ditto */ +#endif +static char *swapf = _PATH_DEVNULL; /* -W | -w */ +static int dropgid; /* ditto */ +static int xflag; /* -x | -A or -e */ -enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT; - -static char *fmt __P((char **(*)(kvm_t *, const struct kinfo_proc *, int), - KINFO *, char *, int)); -static char *kludge_oldps_options __P((char *)); -static int pscomp __P((const void *, const void *)); -static void saveuser __P((KINFO *)); -static void scanvars __P((void)); -static void dynsizevars __P((KINFO *)); -static void sizevars __P((void)); -static void usage __P((void)); -static uid_t *getuids(const char *, int *); - -char dfmt[] = "pid tt state time command"; -char jfmt[] = "user pid ppid pgid sess jobc state tt time command"; -char lfmt[] = "uid pid ppid cpu pri nice vsz rss wchan state tt time command"; -char o1[] = "pid"; -char o2[] = "tt state time command"; -char ufmt[] = "user pid %cpu %mem vsz rss tt state start time command"; -char vfmt[] = "pid state time sl re pagein vsz rss lim tsiz %cpu %mem command"; +static struct winsize ws; +static int needuser, needcomm; /* scanvars() */ -kvm_t *kd; +/* + * Local functions + */ +static void addentry __P((char *, void **, int *, enum entry)); +static void dynsizevars __P((KINFO *)); +static char *fmt __P((kvm_t *, + char **(*)(kvm_t *, const struct kinfo_proc *, int), + KINFO *, char *, int)); +static char *kludge_oldps_options __P((char *)); +static void bsd_parseopts __P((int, char *const *)); +#if defined(COMPAT_SUSV2) +static void susv2_parseopts __P((int, char *const *)); +#endif +static int pscomp __P((const void *, const void *)); +static void saveuser __P((kvm_t *, KINFO *)); +static void scanvars __P((void)); +static void sizevars __P((void)); +static void usage __P((void)); int main(argc, argv) int argc; char *argv[]; { - struct kinfo_proc *kp; - struct varent *vent; - struct winsize ws; - dev_t ttydev; - pid_t pid; - uid_t *uids; - int all, ch, flag, i, fmt, lineno, nentries, dropgid; - int prtheader, wflag, what, xflg, uid, nuids; - char *nlistf, *memf, errbuf[_POSIX2_LINE_MAX]; + kvm_t *kd; /* kvm file descriptor */ + struct kinfo_proc *kp; /* kvm_getprocs() */ + VARENT *vent; + int i, j, lineno; /* indices */ + int what, flag, nentries; /* kvm_getprocs() */ + char errbuf[_POSIX2_LINE_MAX]; /* kvm_openfiles() */ +#if defined(COMPAT_SUSV2) + char *cp; +#endif (void) setlocale(LC_ALL, ""); @@ -138,52 +193,340 @@ else termwidth = ws.ws_col - 1; +#if defined(COMPAT_SUSV2) + if ((cp = strrchr(argv[0], '/')) != NULL) + cp++; + else + cp = argv[0]; + susv2 = strchr(cp, '5') != NULL; + if ((cp = getenv(SUSV2ENV)) != NULL) + susv2 = atoi(cp); /* XXX ERANGE */ +#endif + if (argc > 1) argv[1] = kludge_oldps_options(argv[1]); - all = fmt = prtheader = wflag = xflg = 0; - pid = -1; - nuids = 0; - uids = NULL; - ttydev = NODEV; - dropgid = 0; - memf = nlistf = _PATH_DEVNULL; - while ((ch = getopt(argc, argv, +#if defined(COMPAT_SUSV2) + if (susv2) + susv2_parseopts(argc, argv); + else +#endif + bsd_parseopts(argc, argv); + + argc -= optind; + argv += optind; + +#ifdef BACKWARD_COMPATIBILITY +#if defined(COMPAT_SUSV2) + if (!susv2) +#endif + if (*argv) { + nlistf = *argv; + if (*++argv) { + memf = *argv; +#if defined(NO_SWAP) + if (*++argv) + swapf = *argv; +#endif + } + } +#endif + /* + * Discard setgid privileges if not the running kernel so that bad + * guys can't print interesting stuff from kernel memory. + */ + if (dropgid) { + setgid(getgid()); + setuid(getuid()); + } + + kd = kvm_openfiles(nlistf, memf, swapf, O_RDONLY, errbuf); + if (kd == 0) + errx(1, "%s", errbuf); + + /* XXX - should be cleaner */ + if (!all + && !(nuids + npids + ndevs) +#if defined(COMPAT_SUSV2) + && !(ngids + npgids + nruids + ncmds) +#endif + ) { + char buf[UIDLEN]; + + snprintf(buf, sizeof(buf), "%d", getuid()); + addentry(buf, (void **)&uids, &nuids, UID); + } + + /* + * scan requested variables, noting what structures are needed, + * and adjusting header widths as appropriate. + */ + scanvars(); + + /* + * get proc list + */ + if (nuids == 1) { + what = KERN_PROC_UID; + flag = *uids; + } else if (npids == 1) { + what = KERN_PROC_PID; + flag = *pids; + } else if (ndevs == 1) { + what = KERN_PROC_TTY; + flag = *devs; + } +#if defined(COMPAT_SUSV2) + else if (npgids == 1) { + what = KERN_PROC_PGRP; + flag = *pgids; + } else if (nruids == 1) { + what = KERN_PROC_RUID; + flag = *ruids; + } +#endif + else { + what = KERN_PROC_ALL; + flag = 0; + } + + /* + * select procs + */ + if ((kp = kvm_getprocs(kd, what, flag, &nentries)) == 0) + errx(1, "%s", kvm_geterr(kd)); + if ((kinfo = malloc(nentries * sizeof(*kinfo))) == NULL) + err(1, "malloc"); + for (i = nentries; --i >= 0; ++kp) { + kinfo[i].ki_p = kp; + if (needuser) + saveuser(kd, &kinfo[i]); + dynsizevars(&kinfo[i]); + } + + sizevars(); + + /* + * print header + */ + printheader(); + + /* + * oops! no proc, goodbye. + */ + if (nentries == 0) + exit(1); + + /* + * sort proc list + */ + qsort(kinfo, nentries, sizeof(KINFO), pscomp); + + /* + * for each proc, call each variable output function. + */ + for (i = lineno = 0; i < nentries; i++) { + if (xflag == 0 && (KI_EPROC(&kinfo[i])->e_tdev == NODEV || + (KI_PROC(&kinfo[i])->p_flag & P_CONTROLT) == 0)) + continue; + if (nuids > 1) { + for (j = 0; j < nuids; j++) + if (KI_EPROC(&kinfo[i])->e_ucred.cr_uid == + uids[j]) + break; + if (j == nuids) + continue; + } +#if defined(COMPAT_SUSV2) + if (npids > 1) { + for (j = 0; j < npids; j++) + if (KI_PROC(&kinfo[i])->p_pid == pids[j]) + break; + if (j == npids) + continue; + } + if (ndevs > 1) { + for (j = 0; j < ndevs; j++) + if (KI_EPROC(&kinfo[i])->e_tdev == devs[j]) + break; + if (j == ndevs) + continue; + } + if (ngids > 0) { + for (j = 0; j < ngids; j++) + if (KI_EPROC(&kinfo[i])->e_ucred.cr_gid == + gids[j]) + break; + if (j == ngids) + continue; + } + if (npgids > 1) { + for (j = 0; j < npgids; j++) + if (KI_EPROC(&kinfo[i])->e_pgid == pgids[j]) + break; + if (j == npgids) + continue; + } + if (nruids > 1) { + for (j = 0; j < nruids; j++) + if (KI_EPROC(&kinfo[i])->e_pcred.p_ruid == + ruids[j]) + break; + if (j == nruids) + continue; + } + if (ncmds > 0) { + for (j = 0; j < ncmds; j++) + if (!strncmp(KI_PROC(&kinfo[i])->p_comm, + cmds[j], + MIN(MAXCOMLEN, strlen(cmds[j])))) + break; + if (j == ncmds) + continue; + } +#endif + STAILQ_FOREACH(vent, &varlist, list) { + (vent->var->oproc)(&kinfo[i], vent); + if (STAILQ_NEXT(vent, list) != NULL) + (void)putchar(' '); + } + (void)putchar('\n'); + if (prtheader && lineno++ == prtheader - 4) { + (void)putchar('\n'); + printheader(); + lineno = 0; + } + } + /* XXX needed ? */ + free(uids); +#if defined(COMPAT_SUSV2) + free(devs); + free(gids); + free(pids); + free(pgids); + free(ruids); +#endif + + exit(eval); +} + +static void +bsd_parseopts(int argc, char *const *argv) +{ + static char optstr[OPTLEN]; + static char optfmt[] = "%s%s%s%s%s"; + static char *opts = "aCceghjLlM:mN:O:o:p:rSTt:U:uvwx"; #if defined(LAZY_PS) - "aCcefghjLlM:mN:O:o:p:rSTt:U:uvwx")) != -1) + static char optf[] = "f"; +#else + static char optf[] = ""; +#endif +#if defined(COMPAT_SUSV2) + static char optb[] = "B"; + static char optv[] = "V"; #else - "aCceghjLlM:mN:O:o:p:rSTt:U:uvwx")) != -1) + static char optb[] = ""; + static char optv[] = ""; #endif - switch((char)ch) { +#if defined(NO_SWAP) + static char optw[] = ""; +#else + static char optw[] = "W:"; +#endif + static char o1fmt[] = "pid"; + static char o2fmt[] = "tt state time command"; +#if defined(COMPAT_BSD44) + static char dfmt[] = "pid tt state time command"; + static char jfmt[] = "\ +user pid ppid pgid sess jobc state tt time command"; + static char lfmt[] = "\ +uid pid ppid cpu pri nice vsz rss wchan state tt time command"; + static char ufmt[] = "\ +user pid %cpu %mem vsz rss tt state start time command"; + static char vfmt[] = "\ +pid state time sl re pagein vsz rss lim tsiz %cpu %mem command"; +#else + static char fmt[] = "\ +user[ju] uid[l] pid[djl1uv] ppid[jl] pgid[j] sess[j] jobc[j] cpu[l] \ +pri[l] nice[l] %cpu[u] %mem[u] vsz[lu] rss[lu] wchan[l] tt[d2u] \ +state[djl2uv] tt[jl] start[u] time[djl2uv] sl[v] re[v] pagein[v] \ +vsz[v] rss[v] lim[v] tsiz[v] %cpu[v] %mem[v] command[djl2uv]"; +#endif + + int ch; +#if defined(COMPAT_BSD44) + int fmt; +#else + int jflag; /* -j */ + int lflag; /* -l */ + int uflag; /* -u */ + int vflag; /* -v */ + int oflag; /* -O or -o */ + char *ufmt; /* ditto */ + int nufmt; +#endif + int wflag; /* -w */ + +#if defined(COMPAT_BSD44) + fmt = 0; +#else + jflag = lflag = oflag = uflag = vflag = nufmt = 0; + ufmt = NULL; +#endif + wflag = 0; + + (void)snprintf(optstr, sizeof(optstr), optfmt, + opts, optb, optf, optv, optw); + + while ((ch = getopt(argc, argv, optstr)) != -1) + switch(ch) { case 'a': all = 1; break; +#if defined(COMPAT_SUSV2) + case 'B': /* no-op */ + break; +#endif case 'C': rawcpu = 1; break; case 'c': cflag = 1; break; - case 'e': /* XXX set ufmt */ + case 'e': /* XXX set ufmt */ needenv = 1; break; - case 'g': - break; /* no-op */ +#if defined(LAZY_PS) + case 'f': + if (getuid() == 0 || getgid() == 0) + forceuread = 1; + break; +#endif + case 'g': /* no-op */ + break; case 'h': prtheader = ws.ws_row > 5 ? ws.ws_row : 22; break; case 'j': - parsefmt(jfmt); - fmt = 1; +#if defined(COMPAT_BSD44) + bsd_parsefmt(jfmt); jfmt[0] = '\0'; + fmt = 1; +#else + jflag = 1; +#endif break; case 'L': showkey(); exit(0); case 'l': - parsefmt(lfmt); - fmt = 1; +#if defined(COMPAT_BSD44) + bsd_parsefmt(lfmt); lfmt[0] = '\0'; + fmt = 1; +#else + lflag = 1; +#endif break; case 'M': memf = optarg; @@ -197,25 +540,37 @@ dropgid = 1; break; case 'O': - parsefmt(o1); - parsefmt(optarg); - parsefmt(o2); - o1[0] = o2[0] = '\0'; +#if defined(COMPAT_BSD44) + bsd_parsefmt(o1fmt); + bsd_parsefmt(optarg); + bsd_parsefmt(o2fmt); + o1fmt[0] = o2fmt[0] = '\0'; fmt = 1; +#else + /* XXX quick and dirty hack, need to be rewritten */ + if (o1fmt[0]) { + addentry(o1fmt, (void **)&ufmt, &nufmt, FMT); + o1fmt[0] = '\0'; + } + addentry(optarg, (void **)&ufmt, &nufmt, FMT); + oflag = 1; +#endif break; case 'o': - parsefmt(optarg); +#if defined(COMPAT_BSD44) + bsd_parsefmt(optarg); fmt = 1; - break; -#if defined(LAZY_PS) - case 'f': - if (getuid() == 0 || getgid() == 0) - forceuread = 1; - break; +#else + addentry(optarg, (void **)&ufmt, &nufmt, FMT); + oflag = 1; #endif + break; case 'p': - pid = atol(optarg); - xflg = 1; +#if defined(COMPAT_BSD44) + npids = 0; +#endif + addentry(optarg, (void **)&pids, &npids, PID); + xflag = 1; break; case 'r': sortby = SORTCPU; @@ -228,217 +583,465 @@ errx(1, "stdin: not a terminal"); /* FALLTHROUGH */ case 't': { - struct stat sb; - char *ttypath, pathbuf[PATH_MAX]; - - if (strcmp(optarg, "co") == 0) - ttypath = _PATH_CONSOLE; - else if (*optarg != '/') - (void)snprintf(ttypath = pathbuf, - sizeof(pathbuf), "%s%s", _PATH_TTY, optarg); - else - ttypath = optarg; - if (stat(ttypath, &sb) == -1) - err(1, "%s", ttypath); - if (!S_ISCHR(sb.st_mode)) - errx(1, "%s: not a terminal", ttypath); - ttydev = sb.st_rdev; +#if defined(COMPAT_BSD44) + ndevs = 0; +#endif + addentry(optarg, (void **)&devs, &ndevs, DEV); break; } case 'U': - uids = getuids(optarg, &nuids); - xflg++; /* XXX: intuitive? */ +#if defined(COMPAT_BSD44) + nuids = 0; +#endif + addentry(optarg, (void **)&uids, &nuids, UID); + xflag = 1; /* XXX intuitive? */ break; case 'u': - parsefmt(ufmt); sortby = SORTCPU; - fmt = 1; +#if defined(COMPAT_BSD44) + bsd_parsefmt(ufmt); ufmt[0] = '\0'; + fmt = 1; +#else + uflag = 1; +#endif break; +#if defined(COMPAT_SUSV2) + case 'V': + susv2 = 1; + susv2_parseopts(argc, argv); + return; +#endif case 'v': - parsefmt(vfmt); sortby = SORTMEM; - fmt = 1; +#if defined(COMPAT_BSD44) + bsd_parsefmt(vfmt); vfmt[0] = '\0'; + fmt = 1; +#else + vflag = 1; +#endif break; +#if defined(NO_SWAP) + case 'W': + swapf = optarg; + dropgid = 1; + break; +#endif case 'w': if (wflag) termwidth = UNLIMITED; else if (termwidth < 131) termwidth = 131; - wflag++; + wflag = 1; break; case 'x': - xflg = 1; + xflag = 1; break; case '?': default: usage(); } - argc -= optind; - argv += optind; -#define BACKWARD_COMPATIBILITY -#ifdef BACKWARD_COMPATIBILITY - if (*argv) { - nlistf = *argv; - if (*++argv) { - memf = *argv; +#if defined(COMPAT_BSD44) + if (!fmt) + bsd_parsefmt(dfmt); +#else + if (oflag) { + if (!o1fmt[0]) { + addentry(o2fmt, (void **)&ufmt, &nufmt, FMT); + o2fmt[0] = '\0'; } + susv2_parsefmt(ufmt, NULL); + free(ufmt); /* XXX needed? */ + } else { + char flags[5]; /* jluv\0 | d\0 */ + char *cp; + + cp = flags; + if (jflag) + *cp++ = 'j'; + if (lflag) + *cp++ = 'l'; + if (uflag) + *cp++ = 'u'; + if (vflag) + *cp++ = 'v'; + if (cp == flags) + *cp++ = 'd'; + *cp = '\0'; + susv2_parsefmt(fmt, flags); } #endif - /* - * Discard setgid privileges if not the running kernel so that bad - * guys can't print interesting stuff from kernel memory. - */ - if (dropgid) { - setgid(getgid()); - setuid(getuid()); - } +} - kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); - if (kd == 0) - errx(1, "%s", errbuf); +#if defined(COMPAT_SUSV2) +static void +susv2_parseopts(int argc, char *const *argv) +{ + static char *opts = "AaBC:defg:G:jLlm:n:o:p:t:u:U:Vw:"; + static char fmt[] = "\ +f[lx] s[lx] user[fx] uid[l] pid[dfjlx] ppid[flx] pgid[j] sid[j] \ +c[flx] pri[lx] nice[lx] addr[lx] vsz[lx] wchan[lx] stime[fx] \ +tt[dfjlx] time[dfjlx] comm[djl] args[fx]"; /* x means both f and l */ + + int ch; + int fflag = 0; /* -f */ + int jflag = 0; /* -j */ + int lflag = 0; /* -l */ + int oflag = 0; /* -o */ + char *ufmt; /* ditto */ + int nufmt; + + fflag = jflag = lflag = oflag = nufmt = 0; + ufmt = NULL; + + while ((ch = getopt(argc, argv, opts)) != -1) + switch(ch) { + case 'A': + xflag = 1; + break; + case 'a': + all = 1; + break; + case 'B': + susv2 = 0; + bsd_parseopts(argc, argv); + return; + case 'C': + addentry(optarg, (void **)&cmds, &ncmds, CMD); + all = xflag = 1; + break; +#if 0 + case 'c': /* not yet */ + break; +#endif + case 'd': + all = 1; + break; + case 'e': + all = xflag = 1; + break; + case 'f': + fflag = 1; + termwidth = UNLIMITED; + break; + case 'g': + addentry(optarg, (void **)&pgids, &npgids, PGID); + all = xflag = 1; + break; + case 'G': + addentry(optarg, (void **)&gids, &ngids, GID); + break; + case 'j': + jflag = 1; + break; + case 'L': + showkey(); + exit(0); + case 'l': + lflag = 1; + break; + case 'm': + memf = optarg; + dropgid = 1; + break; + case 'n': + nlistf = optarg; + dropgid = 1; + break; + case 'o': + addentry(optarg, (void **)&ufmt, &nufmt, FMT); + oflag = 1; + break; + case 'p': + addentry(optarg, (void **)&pids, &npids, PID); + break; + case 't': + addentry(optarg, (void **)&devs, &ndevs, DEV); + break; + case 'u': + addentry(optarg, (void **)&uids, &nuids, UID); + break; + case 'U': + addentry(optarg, (void **)&ruids, &nruids, UID); + break; + case 'V': /* no-op */ + break; + case 'w': + swapf = optarg; + dropgid = 1; + break; +#if 0 + case 'y': /* not yet */ + break; +#endif + case '?': + default: + usage(); + } - if (!fmt) - parsefmt(dfmt); + if (oflag) { + susv2_parsefmt(ufmt, NULL); + free(ufmt); /* XXX needed? */ + } else { + char flags[3]; /* d\0 | jx\0 */ + char *cp; - /* XXX - should be cleaner */ - if (!all && ttydev == NODEV && pid == -1 && !nuids) { - if ((uids = malloc(sizeof (*uids))) == NULL) - errx(1, "malloc: %s", strerror(errno)); - nuids = 1; - *uids = getuid(); + cp = flags; + if (fflag && lflag) + *cp++ = 'x'; + else if (fflag) + *cp++ = 'f'; + else if (lflag) + *cp++ = 'l'; + if (jflag) + *cp++ = 'j'; + if (cp == flags) + *cp++ = 'd'; + *cp = '\0'; + susv2_parsefmt(fmt, flags); } +} +#endif - /* - * scan requested variables, noting what structures are needed, - * and adjusting header widths as appropriate. - */ - scanvars(); - /* - * get proc list - */ - if (nuids == 1) { - what = KERN_PROC_UID; - flag = *uids; - } else if (ttydev != NODEV) { - what = KERN_PROC_TTY; - flag = ttydev; - } else if (pid != -1) { - what = KERN_PROC_PID; - flag = pid; - } else { - what = KERN_PROC_ALL; - flag = 0; - } - /* - * select procs - */ - if ((kp = kvm_getprocs(kd, what, flag, &nentries)) == 0) - errx(1, "%s", kvm_geterr(kd)); - if ((kinfo = malloc(nentries * sizeof(*kinfo))) == NULL) - err(1, NULL); - for (i = nentries; --i >= 0; ++kp) { - kinfo[i].ki_p = kp; - if (needuser) - saveuser(&kinfo[i]); - dynsizevars(&kinfo[i]); - } +static void +addentry(char *arg, void **entries, int *nentries, enum entry what) +{ + dev_t dev; +#if defined(COMPAT_SUSV2) + char *fmt; + gid_t gid; + pid_t pgid; + char *cmd; +#endif + uid_t uid; + pid_t pid; + size_t len, lo, hi, have, need, size; + struct stat sb; + struct passwd *pwd; +#if defined(COMPAT_SUSV2) + struct group *grp; +#endif + char buf[MAX(UT_NAMESIZE + 1, PATH_MAX)]; + char *ttypath, pathbuf[PATH_MAX]; - sizevars(); + dev = 0; uid = 0; pid = 0; size = 0; /* make gcc happy */ +#if defined(COMPAT_SUSV2) + gid = 0; pgid = 0; fmt = 0; /* ditto */ +#endif - /* - * print header - */ - printheader(); - if (nentries == 0) - exit(1); - /* - * sort proc list - */ - qsort(kinfo, nentries, sizeof(KINFO), pscomp); - /* - * for each proc, call each variable output function. - */ - for (i = lineno = 0; i < nentries; i++) { - if (xflg == 0 && (KI_EPROC(&kinfo[i])->e_tdev == NODEV || - (KI_PROC(&kinfo[i])->p_flag & P_CONTROLT ) == 0)) - continue; - if (nuids > 1) { - for (uid = 0; uid < nuids; uid++) - if (KI_EPROC(&kinfo[i])->e_ucred.cr_uid == - uids[uid]) - break; - if (uid == nuids) + for (; (len = strcspn(arg, SEP)) > 0; + arg += len + strspn(arg + len, SEP)) { + have = *nentries; + need = 1; + + switch (what) { + case DEV: + if ((len + (strlen(_PATH_TTY) * *arg != '/')) + >= sizeof(buf)) { + warnx("%.*s: path name too long", + (int)len, arg); continue; - } - for (vent = vhead; vent; vent = vent->next) { - (vent->var->oproc)(&kinfo[i], vent); - if (vent->next != NULL) - (void)putchar(' '); - } - (void)putchar('\n'); - if (prtheader && lineno++ == prtheader - 4) { - (void)putchar('\n'); - printheader(); - lineno = 0; - } - } - free(uids); + } + strncpy(buf, arg, len); + buf[len] = '\0'; - exit(eval); -} + if (strcmp(buf, "co") == 0) + ttypath = _PATH_CONSOLE; + else if (*buf != '/') + (void)snprintf(ttypath = pathbuf, + sizeof(buf), "%s%s", +#if !defined(COMPAT_BSD44) + !strncmp(buf, "tty", 3) ? _PATH_DEV : +#endif + _PATH_TTY, buf); + else + ttypath = buf; + if (stat(ttypath, &sb) == -1) + err(1, "%s", ttypath); + if (!S_ISCHR(sb.st_mode)) + errx(1, "%s: not a terminal", ttypath); + dev = sb.st_rdev; + size = sizeof(dev_t); + break; +#if defined(COMPAT_SUSV2) + case FMT: + fmt = arg; + size = sizeof(char); + need += len + 1; + break; + case GID: + if (len >= sizeof(buf)) { + warnx("%.*s: group name too long", + (int)len, arg); + continue; + } + strncpy(buf, arg, len); + buf[len] = '\0'; +#if !defined(COMPAT_BSD44) + gid = (gid_t)strtoul(buf, NULL, 10); /* XXX ERANGE */ +#endif -uid_t * -getuids(const char *arg, int *nuids) -{ - char name[UT_NAMESIZE + 1]; - struct passwd *pwd; - uid_t *uids, *moreuids; - int l, alloc; + if ((grp = getgrnam(buf)) == NULL +#if !defined(COMPAT_BSD44) +#if defined(COMPAT_SUSV2) + /* && susv2 */ +#endif + && (grp = getgrgid(gid)) == NULL +#endif + ) { + warnx("%s: no such group", buf); + continue; + } + gid = grp->gr_gid; + size = sizeof(gid); + break; + case PGID: + if (len >= sizeof(buf)) { + warnx("%.*s: process group id too big", + (int)len, arg); + continue; + } + strncpy(buf, arg, len); + buf[len] = '\0'; + + pgid = (pid_t)strtoul(buf, NULL, 10); /* XXX ERANGE */ + size = sizeof(pid_t); + break; + case CMD: + cmd = arg; + size = sizeof(char *); + arg [len++] = '\0'; + break; +#endif + case UID: + if (len >= sizeof(buf)) { + warnx("%.*s: login name too long", + (int)len, arg); + continue; + } + strncpy(buf, arg, len); + buf[len] = '\0'; +#if !defined(COMPAT_BSD44) + uid = (uid_t)strtoul(buf, NULL, 10); /* XXX ERANGE */ +#endif + if ((pwd = getpwnam(buf)) == NULL +#if !defined(COMPAT_BSD44) +#if defined(COMPAT_SUSV2) + /* && susv2 */ +#endif + && (pwd = getpwuid(uid)) == NULL +#endif + ) { + warnx("%s: no such user", buf); + continue; + } + uid = pwd->pw_uid; + size = sizeof(uid); + break; + case PID: + if (len >= sizeof(buf)) { + warnx("%.*s: process id too big", + (int)len, arg); + continue; + } + strncpy(buf, arg, len); + buf[len] = '\0'; - alloc = 0; - *nuids = 0; - uids = NULL; - for (; (l = strcspn(arg, SEP)) > 0; arg += l + strspn(arg + l, SEP)) { - if (l >= sizeof name) { - warnx("%.*s: name too long", l, arg); - continue; + pid = (pid_t)strtoul(buf, NULL, 10); /* XXX ERANGE */ + size = sizeof(pid_t); + break; } - strncpy(name, arg, l); - name[l] = '\0'; - if ((pwd = getpwnam(name)) == NULL) { - warnx("%s: no such user", name); - continue; + + lo = rounddown(have + need, BUCKETS); + hi = roundup2(have, BUCKETS); + if (lo >= hi) { + int n = roundup2(have + need, BUCKETS); + if ((*entries = realloc(*entries, n * size)) == NULL) + err(1, "realloc"); } - if (*nuids >= alloc) { - alloc = (alloc + 1) << 1; - moreuids = realloc(uids, alloc * sizeof (*uids)); - if (moreuids == NULL) { - free(uids); - errx(1, "realloc: %s", strerror(errno)); - } - uids = moreuids; + + switch (what) { + case DEV: + *((dev_t **)entries)[(*nentries)++] = dev; + break; +#if defined(COMPAT_SUSV2) + case FMT: + (*((char **)entries))[(*nentries)++] = ' '; + strncpy((*((char **)entries))+*nentries, fmt, len); + *nentries += len; + (*((char **)entries))[*nentries] = '\0'; + break; + case GID: + (*((gid_t **)entries))[(*nentries)++] = gid; + break; + case PGID: + (*((pid_t **)entries))[(*nentries)++] = pgid; + break; + case CMD: + (*((char ***)entries))[(*nentries)++] = cmd; + break; +#endif + case UID: + (*((uid_t **)entries))[(*nentries)++] = uid; + break; + case PID: + (*((pid_t **)entries))[(*nentries)++] = pid; + break; } - uids[(*nuids)++] = pwd->pw_uid; } - endpwent(); - if (!*nuids) - errx(1, "No users specified"); + switch (what) { + case UID: + endpwent(); + break; +#if defined(COMPAT_SUSV2) + case GID: + endgrent(); + break; + default: /* avoid gcc warnings */ + } +#endif - return uids; + if (!*nentries) { + switch (what) { + case DEV: + arg = "terminal"; + break; +#if defined(COMPAT_SUSV2) + case FMT: + arg = "format"; + break; + case GID: + arg = "group"; + break; + case PGID: + arg = "process group id"; + break; + case CMD: + arg = "process name"; + break; +#endif + case UID: + arg = "user"; + break; + case PID: + arg = "process id"; + break; + } + errx(1, "no %s specified", arg); + } } static void scanvars() { - struct varent *vent; + VARENT *vent; VAR *v; - for (vent = vhead; vent; vent = vent->next) { + STAILQ_FOREACH(vent, &varlist, list) { v = vent->var; if (v->flag & DSIZ) { v->dwidth = v->width; @@ -455,11 +1058,11 @@ dynsizevars(ki) KINFO *ki; { - struct varent *vent; + VARENT *vent; VAR *v; int i; - for (vent = vhead; vent; vent = vent->next) { + STAILQ_FOREACH(vent, &varlist, list) { v = vent->var; if (!(v->flag & DSIZ)) continue; @@ -474,11 +1077,11 @@ static void sizevars() { - struct varent *vent; + VARENT *vent; VAR *v; int i; - for (vent = vhead; vent; vent = vent->next) { + STAILQ_FOREACH(vent, &varlist, list) { v = vent->var; i = strlen(v->header); if (v->width < i) @@ -489,7 +1092,8 @@ } static char * -fmt(fn, ki, comm, maxlen) +fmt(kd, fn, ki, comm, maxlen) + kvm_t *kd; char **(*fn) __P((kvm_t *, const struct kinfo_proc *, int)); KINFO *ki; char *comm; @@ -497,8 +1101,8 @@ { char *s; - if ((s = - fmt_argv((*fn)(kd, ki->ki_p, termwidth), comm, maxlen)) == NULL) + if ((s = fmt_argv((*fn)(kd, ki->ki_p, termwidth), + comm, maxlen)) == NULL) err(1, NULL); return (s); } @@ -506,7 +1110,8 @@ #define UREADOK(ki) (forceuread || (KI_PROC(ki)->p_flag & P_INMEM)) static void -saveuser(ki) +saveuser(kd, ki) + kvm_t *kd; KINFO *ki; { struct usave *usp; @@ -530,7 +1135,7 @@ * save arguments if needed */ if (needcomm && (UREADOK(ki) || (KI_PROC(ki)->p_args != NULL))) { - ki->ki_args = fmt(kvm_getargv, ki, KI_PROC(ki)->p_comm, + ki->ki_args = fmt(kd, kvm_getargv, ki, KI_PROC(ki)->p_comm, MAXCOMLEN); } else if (needcomm) { ki->ki_args = malloc(strlen(KI_PROC(ki)->p_comm) + 3); @@ -539,7 +1144,7 @@ ki->ki_args = NULL; } if (needenv && UREADOK(ki)) { - ki->ki_env = fmt(kvm_getenvv, ki, (char *)NULL, 0); + ki->ki_env = fmt(kd, kvm_getenvv, ki, (char *)NULL, 0); } else if (needenv) { ki->ki_env = malloc(3); strcpy(ki->ki_env, "()"); @@ -548,13 +1153,14 @@ } } +#define VSIZE(k) (KI_EPROC(k)->e_vm.vm_dsize + KI_EPROC(k)->e_vm.vm_ssize + \ + KI_EPROC(k)->e_vm.vm_tsize) + static int pscomp(a, b) const void *a, *b; { int i; -#define VSIZE(k) (KI_EPROC(k)->e_vm.vm_dsize + KI_EPROC(k)->e_vm.vm_ssize + \ - KI_EPROC(k)->e_vm.vm_tsize) if (sortby == SORTCPU) return (getpcpu((KINFO *)b) - getpcpu((KINFO *)a)); @@ -586,12 +1192,16 @@ len = strlen(s); if ((newopts = ns = malloc(len + 2)) == NULL) - err(1, NULL); + err(1, "malloc"); /* * options begin with '-' */ - if (*s != '-') + if (*s != '-') { +#if defined(COMPAT_SUSV2) + susv2 = 0; +#endif *ns++ = '-'; /* add option flag */ + } /* * gaze to end of argv[1] */ @@ -634,10 +1244,42 @@ static void usage() { +#if defined(LAZY_PS) + static char optf[] = "f"; +#else + static char optf[] = ""; +#endif +#if defined(COMPAT_BSD44) + static char list[] = ""; +#else + static char list[] = "list"; +#endif +#if defined(COMPAT_SUSV2) + static char optb[] = "B"; + static char optv[] = "V"; +#else + static char optb[] = ""; + static char optv[] = ""; +#endif +#if defined(NO_SWAP) + static char optw[] = ""; +#else + static char optw[] = " [-W swap]"; +#endif - (void)fprintf(stderr, "%s\n%s\n%s\n", - "usage: ps [-aChjlmrSTuvwx] [-O|o fmt] [-p pid] [-t tty] [-U user]", - " [-M core] [-N system]", - " ps [-L]"); +#if defined(COMPAT_SUSV2) + if (susv2) + (void)fprintf(stderr, "\ +usage: ps [-AaBdefjl] [-C cmdlist] [-g pgrplist] [-G grouplist] [-o fmt]\n\ + [-p pidlist] [-t ttylist] [-u userlist] [-U userlist]\n\ + [-m core] [-n system] [-w swap]\n\ +"); + else +#endif + (void)fprintf(stderr, "\ +usage: ps [-a%sC%shjlmrSTuv%swx] [-O|-o fmt] [-p pid%s] [-t tty%s]\n\ + [-U user%s] [-M core] [-N system]%s\n\ + ps [-L]\n\ +", optb, optf, optv, list, list, list, optw); exit(1); } Index: ps.h =================================================================== RCS file: /home/ncvs/src/bin/ps/ps.h,v retrieving revision 1.7 diff -u -r1.7 ps.h --- ps.h 27 Aug 1999 23:14:52 -0000 1.7 +++ ps.h 3 Jun 2001 20:10:12 -0000 @@ -34,6 +34,10 @@ * $FreeBSD: src/bin/ps/ps.h,v 1.7 1999/08/27 23:14:52 peter Exp $ */ +#if !defined(COMPAT_BSD44) && !defined(COMPAT_SUSV2) +#define COMPAT_BSD44 +#endif + #define UNLIMITED 0 /* unlimited terminal width */ enum type { CHAR, UCHAR, SHORT, USHORT, INT, UINT, LONG, ULONG, KPTR }; @@ -56,8 +60,10 @@ } KINFO; /* Variables. */ +typedef STAILQ_HEAD(varlist, varent) VARLIST; + typedef struct varent { - struct varent *next; + STAILQ_ENTRY(varent) list; struct var *var; } VARENT; --/NkBOFFp2J2Af1nK-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020611030857.GB14401>