Index: extern.h
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/extern.h,v
retrieving revision 1.19
diff -p -u -r1.19 extern.h
--- extern.h	2000/06/07 04:57:59	1.19
+++ extern.h	2000/06/11 17:47:08
@@ -43,7 +43,7 @@ struct varent;
 extern double ccpu;
 extern int eval, fscale, mempages, nlistread, rawcpu;
 extern int sumrusage, termwidth, totwidth;
-extern int needenv, needcomm, commandonly, dontuseprocfs, use_procfs;
+extern int needenv, commandonly, dontuseprocfs, use_procfs, sysv;
 extern uid_t myuid;
 extern kvm_t *kd;
 extern VAR var[];
@@ -54,10 +54,12 @@ void	 command __P((struct kinfo_proc2 *,
 void	 cputime __P((struct kinfo_proc2 *, VARENT *, int));
 int	 donlist __P((void));
 int	 donlist_sysctl __P((void));
+void	 etime __P((struct kinfo_proc2 *, VARENT *, int));
 void	 fmt_puts __P((char *, int *));
 void	 fmt_putc __P((int, int *));
 double	 getpcpu __P((struct kinfo_proc2 *));
 double	 getpmem __P((struct kinfo_proc2 *));
+void	 gname __P((struct kinfo_proc2 *, VARENT *, int));
 void	 logname __P((struct kinfo_proc2 *, VARENT *, int));
 void	 longtname __P((struct kinfo_proc2 *, VARENT *, int));
 void	 lstarted __P((struct kinfo_proc2 *, VARENT *, int));
@@ -75,11 +77,14 @@ struct kinfo_proc2
 	*getkinfo_procfs __P((int, int, int *));
 char	**procfs_getargv __P((const struct kinfo_proc2 *, int));
 void	 pvar __P((struct kinfo_proc2 *, VARENT *, int));
+void	 rgname __P((struct kinfo_proc2 *, VARENT *, int));
 void	 rssize __P((struct kinfo_proc2 *, VARENT *, int));
 void	 runame __P((struct kinfo_proc2 *, VARENT *, int));
 void	 showkey __P((void));
+void	 size __P((struct kinfo_proc2 *, VARENT *, int));
 void	 started __P((struct kinfo_proc2 *, VARENT *, int));
 void	 state __P((struct kinfo_proc2 *, VARENT *, int));
+void	 sysv_state __P((struct kinfo_proc2 *, VARENT *, int));
 void	 tdev __P((struct kinfo_proc2 *, VARENT *, int));
 void	 tname __P((struct kinfo_proc2 *, VARENT *, int));
 void	 tsize __P((struct kinfo_proc2 *, VARENT *, int));
Index: keyword.c
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/keyword.c,v
retrieving revision 1.25
diff -p -u -r1.25 keyword.c
--- keyword.c	2000/06/07 04:57:59	1.25
+++ keyword.c	2000/06/11 17:47:08
@@ -88,13 +88,19 @@ VAR var[] = {
 	{"%mem", "%MEM", NULL, 0, pmem},
 	{"acflag", "ACFLG", NULL, 0, pvar, 0, POFF(p_acflag), USHORT, "x"},
 	{"acflg", "", "acflag"},
+	{"addr", "ADDR", NULL, 0, pvar, 0, POFF(p_paddr), KPTR, "x"},
+	{"args", "COMMAND", NULL, LJUST, command},
 	{"blocked", "", "sigmask"},
+	{"c", "C", NULL, 0, pvar, 0, POFF(p_estcpu), UINT, "d"},
 	{"caught", "", "sigcatch"},
-	{"command", "COMMAND", NULL, COMM|LJUST, command},
+	{"comm", "COMMAND", NULL, COMM|LJUST, command},
+	{"command", "COMMAND", NULL, LJUST, command},
 	{"cpu", "CPU", NULL, 0, pvar, 0, POFF(p_estcpu), UINT, "d"},
 	{"cputime", "", "time"},
+	{"etime", "ELAPSED", NULL, 0, etime},
 	{"f", "F", NULL, 0, pvar, 0, POFF(p_flag), INT, "x"},
 	{"flags", "", "f"},
+	{"group", "GROUP", NULL, LJUST, gname},
 	{"holdcnt", "HOLDCNT", NULL, 0, pvar, 0, POFF(p_holdcnt), INT, "d"},
 	{"ignored", "", "sigignore"},
 	{"inblk", "INBLK", NULL, 0, pvar, 0, POFF(p_uru_inblock), ULONG, "d"},
@@ -138,11 +144,13 @@ VAR var[] = {
 	GID("rgid", "RGID", pvar, POFF(p_rgid)),
 	/* XXX */
 	{"rlink", "RLINK", NULL, 0, pvar, 0, POFF(p_back), KPTR, "x"},
+	{"rgroup", "RGROUP", NULL, LJUST, rgname},
 	{"rss", "RSS", NULL, 0, p_rssize},
 	{"rssize", "", "rsz"},
 	{"rsz", "RSZ", NULL, 0, rssize},
 	UID("ruid", "RUID", pvar, POFF(p_ruid)),
 	{"ruser", "RUSER", NULL, LJUST, runame},
+	{"s", "S", NULL, 0, sysv_state},
 	{"sess", "SESS", NULL, 0, pvar, 0, POFF(p_sess), KPTR24, "x"},
 	PID("sid", "SID", pvar, POFF(p_sid)),
 	{"sig", "PENDING",
@@ -159,6 +167,7 @@ VAR var[] = {
 	{"state", "STAT", NULL, LJUST, state},
 	GID("svgid", "SVGID", pvar, POFF(p_gid)),
 	UID("svuid", "SVUID", pvar, POFF(p_uid)),
+	{"sz", "SZ", NULL, 0, size},
 	{"tdev", "TDEV", NULL, 0, tdev},
 	{"time", "TIME", NULL, 0, cputime},
 	PID("tpgid", "TGPID", pvar, POFF(p_tpgid)),
Index: print.c
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/print.c,v
retrieving revision 1.55
diff -p -u -r1.55 print.c
--- print.c	2000/06/08 13:30:40	1.55
+++ print.c	2000/06/11 17:47:08
@@ -111,6 +111,8 @@ static void  doubleprintorsetwidth __P((
 static void  intprintorsetwidth __P((VAR *, int, int));
 static void  strprintorsetwidth __P((VAR *, const char *, int));
 
+static time_t now;
+
 #define	min(a,b)	((a) <= (b) ? (a) : (b))
 #define	max(a,b)	((a) >= (b) ? (a) : (b))
 
@@ -279,6 +281,12 @@ command(ki, ve, mode)
 			left = v->width;
 	} else
 		left = -1;
+
+	if (sysv && P_ZOMBIE(ki)) {
+		fmt_puts("<defunct>", &left);
+		return;
+	}
+
 	if (needenv && kd) {
 		argv = kvm_getenvv2(kd, ki, termwidth);
 		if ((p = argv) != NULL) {
@@ -289,33 +297,34 @@ command(ki, ve, mode)
 			}
 		}
 	}
-	if (needcomm) {
-		name = ki->p_comm;
-		if (!commandonly) {
-			argv = NULL;
-			if (!use_procfs)
-				argv = kvm_getargv2(kd, ki, termwidth);
-			else
-				argv = procfs_getargv(ki, termwidth);
-			if ((p = argv) != NULL) {
-				while (*p) {
-					fmt_puts(*p, &left);
-					p++;
-					fmt_putc(' ', &left);
-				}
-			}
-			if (titlecmp(name, argv)) {
-				fmt_putc('(', &left);
-				fmt_puts(name, &left);
-				fmt_putc(')', &left);
-			}
-			if (use_procfs && argv) {
-				free(argv[0]);
-				free(argv);
+
+	name = ki->p_comm;
+	if (!commandonly) {
+		argv = NULL;
+		if (!use_procfs)
+			argv = kvm_getargv2(kd, ki, termwidth);
+		else
+			argv = procfs_getargv(ki, termwidth);
+		if ((p = argv) != NULL) {
+			while (*p) {
+				fmt_puts(*p, &left);
+				if (v->flag & COMM)
+					break;
+				p++;
+				fmt_putc(' ', &left);
 			}
-		} else {
+		}
+		if (titlecmp(name, argv)) {
+			fmt_putc('(', &left);
 			fmt_puts(name, &left);
+			fmt_putc(')', &left);
 		}
+		if (use_procfs && argv) {
+			free(argv[0]);
+			free(argv);
+		}
+	} else {
+		fmt_puts(name, &left);
 	}
 	if (ve->next && left > 0)
 		printf("%*s", left, "");
@@ -414,6 +423,49 @@ state(k, ve, mode)
 }
 
 void
+sysv_state(k, ve, mode)
+	struct kinfo_proc2 *k;
+	VARENT *ve;
+	int mode;
+{
+	int ch;
+	VAR *v;
+
+	if (mode == WIDTHMODE)
+		/* The header width is the same the max column width */
+		return;
+
+	v = ve->var;
+	switch (k->p_stat) {
+	case SSTOP:
+		ch = 'T';
+		break;
+
+	case SSLEEP:
+		ch = 'S';
+		break;
+
+	case SRUN:
+	case SIDL:
+		ch = 'R';
+		break;
+
+	case SONPROC:
+		ch = 'O';
+		break;
+
+	case SZOMB:
+	case SDEAD:
+		ch = 'Z';
+		break;
+
+	default:
+		ch = '?';
+	}
+	putchar(ch);
+}
+
+void
 pnice(k, ve, mode)
 	struct kinfo_proc2 *k;
 	VARENT *ve;
@@ -462,6 +514,30 @@ runame(k, ve, mode)
 }
 
 void
+gname(k, ve, mode)
+	struct kinfo_proc2 *k;
+	VARENT *ve;
+	int mode;
+{
+	VAR *v;
+
+	v = ve->var;
+	strprintorsetwidth(v, user_from_uid(k->p_gid, 0), mode);
+}
+
+void
+rgname(k, ve, mode)
+	struct kinfo_proc2 *k;
+	VARENT *ve;
+	int mode;
+{
+	VAR *v;
+
+	v = ve->var;
+	strprintorsetwidth(v, user_from_uid(k->p_rgid, 0), mode);
+}
+
+void
 tdev(k, ve, mode)
 	struct kinfo_proc2 *k;
 	VARENT *ve;
@@ -559,10 +635,9 @@ started(k, ve, mode)
 	int mode;
 {
 	VAR *v;
-	static time_t now;
 	time_t startt;
 	struct tm *tp;
-	char buf[100], *cp;
+	char buf[50], *cp;
 
 	/*
 	 * XXX: The maximum width of this field is the same as the header
@@ -606,7 +681,7 @@ lstarted(k, ve, mode)
 {
 	VAR *v;
 	time_t startt;
-	char buf[100];
+	char buf[10];
 
 	v = ve->var;
 	if (!k->p_uvalid) {
@@ -622,13 +697,65 @@ lstarted(k, ve, mode)
 
 	/* assume all times are the same length */
 	if (mode != WIDTHMODE || v->width == 0) {
-		(void)strftime(buf, sizeof(buf) -1, "%c",
+		(void)strftime(buf, sizeof(buf) - 1, "%c",
 		    localtime(&startt));
 		strprintorsetwidth(v, buf, mode);
 	}
 }
 
 void
+etime(k, ve, mode)
+	struct kinfo_proc2 *k;
+	VARENT *ve;
+	int mode;
+{
+	VAR *v;
+	char buf[16];
+	int fmtlen;
+	long d, h, m, s;
+
+	v = ve->var;
+	if (!k->p_uvalid) {
+		/*
+		 * Minimum width is less than header - we don't
+		 * need to check it every time.
+		 */
+		if (mode == PRINTMODE)
+			(void)printf("%*s", v->width, "-");
+		return;
+	}
+
+	if (!now)
+		(void)time(&now);
+
+	s = now - k->p_ustart_sec;
+	m = s / SECSPERMIN;
+	s %= SECSPERMIN;
+	h = m / MINSPERHOUR;
+	m %= MINSPERHOUR;
+	d = h / HOURSPERDAY;
+	h %= HOURSPERDAY;
+
+	if (mode == WIDTHMODE) {
+		if (d == 0) {
+			fmtlen = 8;
+		} else {
+			fmtlen = (int)log10((double)d) + 1 + 9;
+		}
+		if (fmtlen > v->width)
+			v->width = fmtlen;
+	} else {
+		if (d == 0)
+			snprintf(buf, sizeof(buf), "%02ld:%02ld:%02ld",
+			    h, m, s);
+		else
+			snprintf(buf, sizeof(buf), "%ld-%02ld:%02ld:%02ld",
+			    d, h, m, s);
+		strprintorsetwidth(v, buf, mode);
+	}
+}
+
+void
 wchan(k, ve, mode)
 	struct kinfo_proc2 *k;
 	VARENT *ve;
@@ -655,6 +782,18 @@ wchan(k, ve, mode)
 		if (mode == PRINTMODE)
 			(void)printf("%-*s", v->width, "-");
 	}
+}
+
+void
+size(k, ve, mode)
+	struct kinfo_proc2 *k;
+	VARENT *ve;
+	int mode;
+{
+	VAR *v;
+
+	v = ve->var;
+	intprintorsetwidth(v, k->p_vm_rssize, mode);
 }
 
 #define pgtok(a)        (((a)*getpagesize())/1024)
Index: ps.c
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/ps.c,v
retrieving revision 1.40
diff -p -u -r1.40 ps.c
--- ps.c	2000/06/08 13:30:40	1.40
+++ ps.c	2000/06/11 17:47:08
@@ -112,11 +112,13 @@ __RCSID("$NetBSD: ps.c,v 1.40 2000/06/08
  * ARGOPTS must contain all option characters that take arguments
  * (except for 't'!) - it is used in kludge_oldps_options()
  */
-#define	GETOPTSTR	"acCeghjKLlM:mN:O:o:p:rSTt:U:uvW:wx"
+#define	GETOPTSTR	"acCefghjKlLmM:N:o:O:p:rSt:TuU:vwW:x"
 #define	ARGOPTS		"MNOopUW"
 
+#define	SYSVGETOPTSTR	"aAdefg:G:jln:o:p:st:u:U:y"
+
 struct kinfo_proc2 *kinfo;
-struct varent *vhead, *vtail;
+struct varent *vhead;
 
 int	eval;			/* exit value */
 int	rawcpu;			/* -C */
@@ -125,7 +127,7 @@ int	dontuseprocfs;		/* -K */
 int	termwidth;		/* width of screen (0 == infinity) */
 int	totwidth;		/* calculated width of requested variables */
 
-int	needcomm, needenv, commandonly, use_procfs;
+int	needenv, commandonly, use_procfs, sysv;
 uid_t	myuid;
 
 enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT;
@@ -134,10 +136,10 @@ static struct kinfo_proc2
 		*getkinfo_kvm __P((kvm_t *, int, int, int *));
 static char	*kludge_oldps_options __P((char *));
 static int	 pscomp __P((const void *, const void *));
-static void	 scanvars __P((void));
 static void	 usage __P((void));
 int		 main __P((int, char *[]));
 
+/* BSD formats */
 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";
@@ -146,6 +148,586 @@ 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";
 
+/* System V / SUSv2 formats.  Ugh, there must be a better way... */
+char sysv_fmt[]     = "pid tt time command";
+char sysv_jfmt[]    = "pid pgid sid tt time command";
+
+char sysv_ffmt[]    = "user pid ppid " /*c*/ " start tt time command";
+char sysv_fjfmt[]   = "user pid ppid pgid sid " /*c*/ " start tt time command";
+
+char sysv_flfmt[]   = "f s user pid ppid c pri ni addr sz wchan start tty time command";
+char sysv_flyfmt[]  = "s user pid ppid c pri ni rss sz wchan start tty time command";
+char sysv_fljfmt[]  = "f s user pid ppid pgid sid c pri ni addr sz wchan start tty time command";
+char sysv_fljyfmt[] = "s user pid ppid pgid sid c pri ni rss sz wchan start tty time command";
+
+char sysv_lfmt[]    = "f s uid pid ppid c pri ni addr sz wchan tty time command";
+char sysv_lyfmt[]   = "s uid pid ppid c pri ni rss sz wchan tty time command";
+char sysv_ljfmt[]   = "f s uid pid ppid pgid sid c pri ni addr sz wchan tty time command";
+char sysv_ljyfmt[]  = "s uid pid ppid pgid sid c pri ni rss sz wchan tty time command";
+
+
+/* HPUX:
+	def:	"pid tty time comm"
+	-f	"user pid ppid cpu stime tty time args"
+	-l	"flags state uid pid ppid cpu intpri nice addr sz wchan tty time comm"
+	-fl	"flags state user pid ppid cpu intpri nice addr sz wchan stime tty time args"
+	-c	remove "cpu nice", replace "intpri" with "cls pri"
+	-j	add "pgid sid" after "ppid" (or "pid" if no "ppid")
+	-P	add "prmid" (for -l) or "prmgrp" (for -f or -fl) after "pid"
+	-H	Shows the process hierarchy.  Each process is displayed
+		under its parent, and the contents of the args or comm
+		column for that process is indented from that of its
+		parent.  Note that this option is expensive in both
+		memory and speed.
+
+      The column names and their meanings are given below.  Except where
+      noted, the default heading for each column is the uppercase form of
+      the column name.
+
+           addr           The memory address of the process, if resident;
+                          otherwise, the disk address.
+
+           args           The command line given when the process was
+                          created.  This column should be the last one
+                          specified, if it is desired.  Only a subset of the
+                          command line is saved by the kernel; as much of
+                          the command line will be displayed as is
+                          available.  The output in this column may contain
+                          spaces.  The default heading for this column is
+                          COMMAND if -o is specified and CMD otherwise.
+
+           cls            Process scheduling class, see rtsched(1).
+
+           comm           The command name.  The output in this column may
+                          contain spaces.  The default heading for this
+                          column is COMMAND if -o is specified and CMD
+                          otherwise.
+
+           cpu            Processor utilization for scheduling.  The default
+                          heading for this column is C.
+
+           etime          Elapsed time of the process.  The default heading
+                          for this column is ELAPSED.
+
+           flags          Flags (octal and additive) associated with the
+                          process:
+
+                                0   Swapped
+                                1   In core
+                                2   System process
+                                4   Locked in core (e.g., for physical I/O)
+                               10   Being traced by another process
+                               20   Another tracing flag
+
+                          The default heading for this column is F.
+
+           intpri         The priority of the process as it is stored
+                          internally by the kernel.  This column is provided
+                          for backward compatibility and its use is not
+                          encouraged.
+
+           gid            The group ID number of the effective process
+                          owner.
+
+           group          The group name of the effective process owner.
+
+           nice           Nice value; used in priority computation (see
+                          nice(1)).  The default heading for this column is
+                          NI.
+
+           pcpu           The percentage of CPU time used by this process
+                          during the last scheduling interval.  The default
+                          heading for this column is %CPU.
+
+           pgid           The process group ID number of the process group
+                          to which this process belongs.
+
+           pid            The process ID number of the process.
+
+           ppid           The process ID number of the parent process.
+
+           pri            The priority of the process.  The meaning of the
+                          value depends on the process scheduling class; see
+                          cls, above, and rtsched(1).
+
+           prmid          The PRM process resource group ID number.
+
+           prmgrp         The PRM process resource group name.
+
+           rgid           The group ID number of the real process owner.
+
+           rgroup         The group name of the real process owner.
+
+           ruid           The user ID number of the real process owner.
+
+           ruser          The login name of the real process owner.
+
+           sid            The session ID number of the session to which this
+                          process belongs.
+
+           state          The state of the process:
+
+                               0    Nonexistent
+                               S    Sleeping
+                               W    Waiting
+                               R    Running
+                               I    Intermediate
+                               Z    Terminated
+                               T    Stopped
+                               X    Growing
+
+                          The default heading for this column is S.
+
+           stime          Starting time of the process.  If the elapsed time
+                          is greater than 24 hours, the starting date is
+                          displayed instead.
+
+           sz             The size in physical pages of the core image of
+                          the process, including text, data, and stack
+                          space.  Physical page size is defined by
+                          _SC_PAGE_SIZE in the header file <unistd.h> (see
+                          sysconf(2) and unistd(5)).
+
+           time           The cumulative execution time for the process.
+
+           tty            The controlling terminal for the process.  The
+                          default heading for this column is TT if -o is
+                          specified and TTY otherwise.
+
+           uid            The user ID number of the effective process owner.
+
+           user           The login name of the effective process owner.
+
+           vsz            The size in kilobytes (1024 byte units) of the
+                          core image of the process.  See column sz, above.
+
+           wchan          The event for which the process is waiting or
+                          sleeping; if there is none, a hyphen (-) is
+                          displayed.
+*/
+
+/* SUS (plus solaris options on first column)
+
+NAME
+
+     ps - report process status
+
+SYNOPSIS
+
+     ps [-aA] [-defl] [-G grouplist] [-o format] ...  [-p proclist]
+             [-t termlist] [-U userlist] [-g grouplist] [-n namelist]
+             [-u userlist]
+
+DESCRIPTION
+
+     The ps utility writes information about processes. You must have appropriate
+     privileges to get information about the specified processes.
+
+     By default, ps selects all processes that have the same effective user ID as the
+     current user, and the same controlling terminal as the terminal from which the
+     command is invoked.
+
+     On some systems, especially multi-level secure systems, ps may be severely
+     restricted and may produce information only about child processes owned by the
+     user. For additional information concerning functionality of the ps utility
+     under these conditions, contact your System Administrator.
+
+     Things can change while ps is running; the snapshot it gives is only true for an
+     instant, and may not be accurate by the time it is displayed.
+
+OPTIONS
+
+     This utility supports the utility syntax guidelines described in the
+     xbdutsyntax(5) reference page.
+
+     With the exception of the -f, -l, and -o options, all of the options shown for
+     ps are used to select processes. If any of these options are specified, the
+     default list of processes is ignored, and ps selects the processes that satisfy
+     any of the selection-criteria options.
+
+     Systems that conform to the Single UNIX Specification support the following
+     options:
+
+*    -A
+         Writes information about all processes.
+*    -a
+         Writes information about all processes associated with terminals. Some
+         systems that conform to the Single UNIX Specification, Version 2 may omit
+         session leaders from this list.
+-c Print information in a format that reflects scheduler properties as described
+   in priocntl(1). The -c option affects the output of the -f and -l options, as
+   described below.
+*    -d
+         Writes information about all processes (except session leaders).
+*    -e
+         Writes information about all processes (equivalent to -A).
+*    -f
+         Generates a full listing.
+
+         Under the -f option, ps tries to determine the command name and arguments
+         given when the process was created, by examining memory or the swap area.
+         Failing this, ps writes the command name, as it would appear without the
+         -f option, in square brackets ( []).
+
+*    -G grouplist
+         Writes information about processes for which the real group ID numbers are
+         given in grouplist. The grouplist must be a single argument in the form of
+         a blank- or comma-separated list.
+*    -g grouplist
+         Writes information about processes for which the session leaders are given
+         in grouplist. The grouplist must be a single argument in the form of a
+         blank- or comma-separated list.
+-j Print session ID and process group ID.
+*    -l
+         (the letter "ell") Generates a long listing.
+-L Print information about each light weight process (lwp) in each selected process.
+   (See below.)
+*    -n namelist
+         Specifies the name of an alternative system namelist file, in place of the
+         default. The default name and the format of a namelist file may vary among
+         systems that conform to the Single UNIX Specification, Version 2.
+*    -o format
+         Writes information according to the format specification given in format.
+         Multiple -o options can be specified; the format specification is
+         interpreted as the space-character-separated concatenation of all the
+         format option-arguments. For additional information, see Format
+         Specifications subsection of ps(1).
+*    -p proclist
+         Writes information about processes for which the process ID numbers are
+         given in proclist. The proclist must be a single argument in the form of a
+         blank- or comma-separated list.
+-P Print the number of the processor to which the process or lwp is bound, if any,
+   under an additional column header, PSR.
+-s sidlist
+   List information on all session leaders whose IDs appear in sidlist.
+*    -t termlist
+         Writes information about processes associated with the list of terminal
+         identifiers given in termlist. The termlist must be a single argument in
+         the form of a blank- or comma-separated list. Terminal identifiers must be
+         given in one of two forms:
+              Device's file name (for example, tty04).
+              If the device's file name starts with tty, just the identifier
+              following those characters (for example, 04 if the device name is
+              tty04).
+*    -U userlist
+         Writes information about processes for which the real user ID numbers or
+         login names are given in userlist. The userlist must be a single argument
+         in the form of a blank- or comma-separated list.
+*    -u userlist
+         Writes information about processes for which the user ID numbers or login
+         names are given in userlist. The userlist must be a single argument in the
+         form of a blank- or comma-separated list. In the listing, the numerical
+         user ID is written unless the -f option is used, in which case the login
+         name is written.
+-y Under a long listing (-l), omit the obsolete F and ADDR columns and include an
+   RSS column to report the resident set size of the process. Under the -y option,
+   both RSS and SZ (see below) will be reported in units of kilobytes instead of
+   pages.
+
+
+EXTENDED DESCRIPTION
+
+     If a signal is received during execution of this utility, the action of the
+     utility follows the guidelines described in the xcuutildef(5) reference page.
+
+     If an error condition occurs, the effects of using this utility may vary among
+     systems that conform to the Single UNIX Specification. For more information, see
+     the xcuutildef(5) reference page.
+
+     The following sections contain additional information for the ps utility:
+
+         Default Output Format subsection of ps(1)
+         Format Specifications subsection of ps(1)
+
+     Default Output Format
+
+     When the -o option is not specified, the standard output format is as follows.
+     The column headings and descriptions of the columns in a ps listing are shown in
+     the following table. The precise meanings of these fields may vary among systems
+     that conform to the Single UNIX Specification, Version 2.
+
+     The words "full" or "long" in the "Type of Listing" column indicate the option
+     (-f or -l, respectively) that causes the corresponding heading to appear; "all"
+     means that the heading always appears. These two options determine only what
+     information is displayed for a process; they do not determine which processes
+     are listed.
+
+     Column Head
+               Type of Listing
+                                               Description
+     F
+               Long
+                          Flags (octal and additive) associated with the process.
+     S
+               Long
+                          The state of the process.
+O  Process is running on a processor.
+S  Sleeping: process is waiting for an event to complete.
+R  Runnable: process is on run queue.
+Z  Zombie state: process terminated and parent not waiting.
+T  Process is stopped, either by a job control signal or because it is being traced.
+     UID
+               Full, long
+                          The user ID number of the process owner. The login name is printed under the
+                          -f option.
+     PID
+               All
+                          The process ID of the process. It is possible to kill a process if this ID is known
+.
+     PPID
+               Full, long
+                          The process ID of the parent process.
+     C
+               Full, long
+                          Processor utilization for scheduling.
+     PRI
+               Long
+                          The priority of the process; higher numbers mean lower priority.
+     NI
+               Long
+                          Nice value; used in priority computation.
+     ADDR
+               Long
+                          The address of the process.
+     SZ
+               Long
+                          The size in blocks of the core image of the process.
+     WCHAN
+               Long
+                          The event for which the process is waiting or sleeping; if blank, the process is
+                          running.
+     STIME
+               Full
+                          Starting time of the process.
+     TTY
+               All
+                          The controlling terminal for the process.
+     TIME
+               All
+                          The cumulative execution time for the process.
+     CMD
+               All
+                          The command name. The full command name and its arguments are written
+                          under the -f option.
+The following two additional columns are printed when the -j option is specified:
+PGID  The process ID of the process group leader.
+SID   The process ID of the session leader.
+
+The following two additional columns are printed when the -L option is specified:
+LWP   The lwp ID of the lwp being reported.
+NLWP  The number of lwps in the process (if -f is also specified).
+
+     A process is marked defunct if it has exited and has a parent, but has not yet
+     been waited for by the parent (to release any remaining system resources,
+     including its process ID).
+
+     Format Specifications
+
+     The format specification supplied with the -o option must be a list of names
+     presented as a single argument, blank-separated (if the argument is quoted) or
+     comma-separated. For each name, ps produces a default header. The default header
+     can be overridden by appending an = (equal sign) and the new text of the header.
+     The rest of the characters in the argument are used as the header text.
+
+     The fields specified are written in the order specified on the command line, and
+     are arranged in columns in the output. The field widths are selected by the
+     system to be at least as wide as the header text (either the default header or a
+     new header supplied with the format).
+
+     If the header text is null (for example, -o user=), the field width is at least as
+     wide as the default header text. If all header text fields are null, no header
+     line is written.
+
+     If the field width is too narrow to display a textual ID (such as a user ID or
+     group ID), the system may use a numeric version. Normally, the system ensures
+     that field widths are large enough for proper display of the fields; but if a
+     large number of fields is selected, fields might be displayed using the minimum
+     widths, to fit the information for each process on one line. One way to ensure
+     adequate width for textual IDs is to override the default header for a field,
+     making it larger than most or all user or group names.
+
+     The following names are recognized in the POSIX locale:
+
+     ruser
+         Real user ID of the process. The displayed ID is the textual user ID, if
+         it can be obtained and the field width permits; otherwise, the ID is a
+         decimal representation.
+     user
+         Effective user ID of the process. The displayed ID is the textual user ID,
+         if it can be obtained and the field width permits; otherwise, the ID is a
+         decimal representation.
+     rgroup
+         Real group ID of the process. The displayed ID is the textual group ID, if
+         it can be obtained and the field width permits; otherwise, the ID is a
+         decimal representation.
+     group
+         Effective group ID of the process. The displayed ID is the textual group
+         ID, if it can be obtained and the field width permits; otherwise, the ID
+         is a decimal representation.
+     pid
+         Decimal value of the process ID.
+     ppid
+         Decimal value of the parent process ID.
+     pgid
+         Decimal value of the process group ID.
+     pcpu
+         Ratio of the CPU time used recently to the CPU time available in the same
+         period, expressed as a percentage. The meaning of "recently" in this
+         context may vary among systems that conform to the Single UNIX
+         Specification, Version 2. The manner in which the available CPU time is
+         determined may also vary.
+     vsz
+         Size of the process in virtual memory (in kilobytes, expressed as a
+         decimal integer).
+     nice
+         Decimal value of the system scheduling priority of the process. For more
+         information about system scheduling priorities, see the nice(1) reference
+         page.
+     etime
+         In the POSIX locale, the elapsed time since the process was started, in
+         the following format, where dd represents the number of days, hh the
+         number of hours, mm the number of minutes, and ss the number of seconds:
+
+
+         [[dd-]hh:]mm:ss
+
+         The dd field is a decimal integer. The hh, mm, and ss fields are two-digit
+         decimal integers, padded on the left with zeros.
+
+     time
+         In the POSIX locale, the cumulative CPU time of the process in the
+         following format:
+
+
+         [dd-]hh:mm:ss
+
+         The dd field is a decimal integer. The hh, mm, and ss fields are two-digit
+         decimal integers, padded on the left with zeros.
+
+     tty
+         Name of the controlling terminal of the process (if any), in the same
+         format used by the who utility.
+     comm
+         Name of the command being executed (argv[0] value), expressed as a string.
+     args
+         Command with all its arguments, expressed as a string.
+
+         The local system may truncate this value to the field width to fit the ps
+         display. On some systems that conform to the Single UNIX Specification,
+         Version 2, further truncation may occur. On some systems, a string
+         displayed by ps may be represented as a version of the argument list that
+         was passed to the command when it started; on other systems, the displayed
+         string may be a version of the arguments as modified by the application.
+         An application should not expect the output of ps to show modifications
+         the application made to an argument list.
+
+The following names are recognized in the Solaris implementation:
+f     Flags (hexadecimal and additive) associated with the process.
+s     The state of the process.
+c     Processor utilization for scheduling (obsolete).
+uid   The effective user ID number of the process as a decimal integer.
+ruid  The real user ID number of the process as a decimal integer.
+gid   The effective group ID number of the process as a decimal integer.
+rgid  The real group ID number of the process as a decimal integer.
+sid   The process ID of the session leader.
+class The scheduling class of the process.
+pri   The priority of the process.  Higher numbers mean higher priority.
+opri  The obsolete priority of the process.  Lower numbers mean higher priority.
+lwp   The decimal value of the lwp ID.  Requesting this formatting option causes
+      one line to be printed for eachlwp in the process.
+nlwp  The number of lwps in the process.
+psr   The number of the processor to which the process or lwp is bound.
+addr  The memory address of the process.
+osz   The total size of the process in virtual memory, in pages.
+wchan The address of an event for which the process is sleeping (if -, the process
+      is running).
+stime The starting time or date of the process, printed with no blanks.
+rss   The resident set size of the process, in kilobytes.
+pmem  The ratio of the process's resident set size to the physical memory on the
+      machine, expressed as a percentage.
+fname The first 8 bytes of the base name of the process's executable file.
+
+     Some fields may not be meaningful on all systems that conform to the Single UNIX
+     Specification, Version 2. In such a case, ps displays a hyphen ( -) in place of
+     the field value.
+
+     Of the standard fields, only the comm and args fields can contain blank
+     characters; all other fields cannot.
+
+     The following table specifies the default header to be used in the POSIX locale
+     corresponding to each format specifier.
+
+        Format Specifier        Default Header
+        args                    COMMAND
+        ppid                    PPID
+        comm                    COMMAND
+        rgroup                  RGROUP
+        etime                   ELAPSED
+        ruser                   RUSER
+        group                   GROUP
+        time                    TIME
+        nice                    NI
+        tty                     TT
+        pcpu                    %CPU
+        user                    USER
+        pgid                    PGID
+        vsz                     VSZ
+        pid                     PID
+
+
+EXIT STATUS
+
+     This utility returns the following exit values:
+
+     0
+         Successful completion.
+     >0
+         An error occurred.
+
+EXAMPLES
+
+                 Example 1: Listing the Currently Running Processes
+
+     The following command displays a full listing of every process running at the
+     time the command is issued:
+
+         ps -e -f
+
+            Example 2: Listing the Running Processes of a Particular User
+
+     The following command displays a full listing of every process running at the
+     time the command is issued. It only displays processes owned by james ( james need
+     not be the same as the requesting user).
+
+         ps -f -u james
+
+                     Example 3: Specifying Multiple Headers
+
+     There is no special quoting mechanism for header text; the header text is
+     treated as the rest of the argument to the -o option. If multiple header changes
+     are needed, multiple -o options can be used, as in the following command:
+
+         ps -o "user=User Name" -o pid=Process\ ID
+
+     As shown in this example, a space can be imbedded in the header text either by
+     quoting the entire argument to the -o option (as in -o "user=User Name") or by
+     escaping the space character (as in -o pid=Process\ ID).
+
+ENVIRONMENT VARIABLES
+
+     The environ(5) reference page provides general information about the following
+     standard environment variables, which can affect the operation of this utility:
+     COLUMNS, LANG, LC_ALL, LC_CTYPE, LC_MESSAGES, LC_TIME, and NLSPATH.
+
+SEE ALSO
+
+     kill(1), nice(1), renice(1), who(1), environ(5), xbdutsyntax(5), xcuutildef(5)
+
+
+               The Single UNIX. Documentation, version 2. Copyright ) 1998 The Open Group.
+
+*/
+
 kvm_t *kd;
 
 int
@@ -156,7 +738,7 @@ main(argc, argv)
 	struct varent *vent;
 	struct winsize ws;
 	int ch, flag, i, fmt, lineno, nentries;
-	int prtheader, wflag, what, xflg, mode;
+	int prtheader, widthflag, what, noctty, nosl, mode;
 	char *nlistf, *memf, *swapf, errbuf[_POSIX2_LINE_MAX];
 	char *ttname;
 
@@ -167,164 +749,322 @@ main(argc, argv)
 		termwidth = 79;
 	else
 		termwidth = ws.ws_col - 1;
+
+	/* Allow for multiple -B/-X options at the beginning. */
+	while (argc > 1 && 
+	    (strcmp(argv[1], "-B") == 0 || strcmp(argv[1], "-X") == 0)) {
+		if (strcmp(argv[1], "-B") == 0)
+			sysv = 0;
+		else
+			sysv = 1;
+		argc--;
+		argv++;
+	}
 
-	if (argc > 1)
+	if (!sysv && argc > 1)
 		argv[1] = kludge_oldps_options(argv[1]);
 
-	fmt = prtheader = wflag = xflg = 0;
+	fmt = prtheader = widthflag = noctty = nosl = 0;
 	what = KERN_PROC_UID;
 	flag = myuid = getuid();
 	memf = nlistf = swapf = NULL;
 	mode = PRINTMODE;
-	while ((ch = getopt(argc, argv, GETOPTSTR)) != -1)
-		switch((char)ch) {
-		case 'a':
-			what = KERN_PROC_ALL;
-			flag = 0;
-			break;
-		case 'c':
-			commandonly = 1;
-			break;
-		case 'e':			/* XXX set ufmt */
-			needenv = 1;
-			break;
-		case 'C':
-			rawcpu = 1;
-			break;
-		case 'g':
-			break;			/* no-op */
-		case 'h':
-			prtheader = ws.ws_row > 5 ? ws.ws_row : 22;
-			break;
-		case 'j':
-			parsefmt(jfmt);
-			fmt = 1;
-			jfmt[0] = '\0';
-			break;
-		case 'K':
-			dontuseprocfs=1;
-			break;
-		case 'L':
-			showkey();
-			exit(0);
-			/* NOTREACHED */
-		case 'l':
-			parsefmt(lfmt);
-			fmt = 1;
-			lfmt[0] = '\0';
-			break;
-		case 'M':
-			memf = optarg;
-			dontuseprocfs = 1;
-			break;
-		case 'm':
-			sortby = SORTMEM;
-			break;
-		case 'N':
-			nlistf = optarg;
-			break;
-		case 'O':
-			parsefmt(o1);
-			parsefmt(optarg);
-			parsefmt(o2);
-			o1[0] = o2[0] = '\0';
-			fmt = 1;
-			break;
-		case 'o':
-			parsefmt(optarg);
-			fmt = 1;
-			break;
-		case 'p':
-			what = KERN_PROC_PID;
-			flag = atol(optarg);
-			xflg = 1;
-			break;
-		case 'r':
-			sortby = SORTCPU;
-			break;
-		case 'S':
-			sumrusage = 1;
-			break;
-		case 'T':
-			if ((ttname = ttyname(STDIN_FILENO)) == NULL)
-				errx(1, "stdin: not a terminal");
-			goto tty;
-		case 't':
-			ttname = optarg;
-		tty: {
-			struct stat sb;
-			char *ttypath, pathbuf[MAXPATHLEN];
-
-			flag = 0;
-			if (strcmp(ttname, "?") == 0)
-				flag = KERN_PROC_TTY_NODEV;
-			else if (strcmp(ttname, "-") == 0)
-				flag = KERN_PROC_TTY_REVOKE;
-			else if (strcmp(ttname, "co") == 0)
-				ttypath = _PATH_CONSOLE;
-			else if (*ttname != '/')
-				(void)snprintf(ttypath = pathbuf,
-				    sizeof(pathbuf), "%s%s", _PATH_TTY, ttname);
-			else
-				ttypath = ttname;
-			what = KERN_PROC_TTY;
-			if (flag == 0) {
-				if (stat(ttypath, &sb) == -1)
-					err(1, "%s", ttypath);
-				if (!S_ISCHR(sb.st_mode))
-					errx(1, "%s: not a terminal", ttypath);
-				flag = sb.st_rdev;
+	if (sysv) {
+		int fflag, jflag, lflag, yflag;
+
+		fflag = jflag = lflag = yflag = 0;
+		while ((ch = getopt(argc, argv, SYSVGETOPTSTR)) != -1)
+			switch((char)ch) {
+			case 'a':
+				what = KERN_PROC_ALL;
+				flag = 0;
+				break;
+			case 'A':
+			case 'e':
+				what = KERN_PROC_ALL;
+				flag = 0;
+				noctty = 1;
+				break;
+#if 0
+			case 'C': /* HPUX XPG4 */
+				/* parse process name list */
+				break;
+#endif
+			case 'd':
+				what = KERN_PROC_ALL;
+				flag = 0;
+				nosl = noctty = 1;
+				break;
+			/* case 'e': - above with 'A' */
+			case 'f':
+				fflag++;
+				break;
+			case 'g':
+			case 'p':
+			case 's':
+				/* XXX: parse list, not single id */
+				switch (ch) {
+				case 'g':
+#if 0
+					what = KERN_PROC_PGID;
+					break;
+#else
+						errx(1, "-g not supported yet");
+#endif
+				case 'p':
+					what = KERN_PROC_PID;
+					break;
+				case 's':
+#if 0
+					what = KERN_PROC_SID;
+					break;
+#else
+						errx(1, "-s not supported yet");
+#endif
+				}
+				flag = atol(optarg);
+				noctty = 1;
+				break;
+			case 'G':
+			case 'u': /* effective uid/username */
+			case 'U': /* real uid/username */
+				/* XXX: parse list, not single username */
+				if (*optarg != '\0') {
+					struct passwd *pw;
+					char *ep;
+
+					switch (ch) {
+					case 'G':
+#if 0
+						what = KERN_PROC_RGID;
+						break;
+#else
+						errx(1, "-G not supported yet");
+#endif
+					case 'u':
+						what = KERN_PROC_UID;
+						break;
+					case 'U':
+						what = KERN_PROC_RUID;
+						break;
+					}
+					pw = getpwnam(optarg);
+					if (pw == NULL) {
+						errno = 0;
+						flag = strtoul(optarg, &ep, 10);
+						if (errno)
+							err(1, "%s", optarg);
+						if (*ep != '\0')
+							errx(1, "%s: illegal user name",
+							    optarg);
+					} else
+						flag = pw->pw_uid;
+				}
+				break;
+			case 'j':
+				jflag++;
+				break;
+			case 'l':
+				lflag++;
+				break;
+			case 'n':
+				nlistf = optarg;
+				break;
+			case 'o':
+				parsefmt(optarg);
+				fmt = 1;
+				break;
+			/* case 'p': - above with 'g' */
+			/* case 's': - above with 'g' */
+			case 't':
+				/* XXX: parse tty list */
+				break;
+			/* case 'u': - above with 'G' */
+			/* case 'U': - above with 'G' */
+			case 'y':
+				yflag++;
+				break;
+			default:
+				usage();
 			}
-			break;
-		}
-		case 'U':
-			if (*optarg != '\0') {
-				struct passwd *pw;
-				char *ep;
-
-				what = KERN_PROC_UID;
-				pw = getpwnam(optarg);
-				if (pw == NULL) {
-					errno = 0;
-					flag = strtoul(optarg, &ep, 10);
-					if (errno)
-						err(1, "%s", optarg);
-					if (*ep != '\0')
-						errx(1, "%s: illegal user name",
-						    optarg);
-				} else
-					flag = pw->pw_uid;
+		if (fmt == 0) {
+			if (fflag && lflag) {
+				parsefmt(yflag ?
+				    (jflag ? sysv_fljyfmt : sysv_flyfmt) :
+				    (jflag ? sysv_fljfmt : sysv_flfmt));
+			} else if (fflag) {
+				parsefmt(jflag ? sysv_fjfmt : sysv_ffmt);
+			} else if (lflag) {
+				parsefmt(yflag ?
+				    (jflag ? sysv_ljyfmt : sysv_lyfmt) :
+				    (jflag ? sysv_ljfmt : sysv_lfmt));
+			} else {
+				parsefmt(jflag ? sysv_jfmt : sysv_fmt);
 			}
-			break;
-		case 'u':
-			parsefmt(ufmt);
-			sortby = SORTCPU;
-			fmt = 1;
-			ufmt[0] = '\0';
-			break;
-		case 'v':
-			parsefmt(vfmt);
-			sortby = SORTMEM;
-			fmt = 1;
-			vfmt[0] = '\0';
-			break;
-		case 'W':
-			swapf = optarg;
-			break;
-		case 'w':
-			if (wflag)
-				termwidth = UNLIMITED;
-			else if (termwidth < 131)
-				termwidth = 131;
-			wflag++;
-			break;
-		case 'x':
-			xflg = 1;
-			break;
-		case '?':
-		default:
-			usage();
 		}
+		if (!fflag)
+			commandonly = 1;
+	} else {
+		while ((ch = getopt(argc, argv, GETOPTSTR)) != -1)
+			switch((char)ch) {
+			case 'a':
+				what = KERN_PROC_ALL;
+				flag = 0;
+				break;
+			case 'c':
+				commandonly = 1;
+				break;
+			case 'C':
+				rawcpu = 1;
+				break;
+			case 'e':			/* XXX set ufmt */
+				needenv = 1;
+				break;
+			case 'f':	/* sysv -ef compatibility */
+				what = KERN_PROC_ALL;
+				flag = 0;
+				noctty = 1;
+				needenv = 0;		/* XXX! */
+				parsefmt(sysv_ffmt);
+				fmt = 1;
+				sysv_ffmt[0] = '\0';
+				break;
+			case 'g':
+				break;			/* no-op */
+			case 'h':
+				prtheader = ws.ws_row > 5 ? ws.ws_row : 22;
+				break;
+			case 'j':
+				parsefmt(jfmt);
+				fmt = 1;
+				jfmt[0] = '\0';
+				break;
+			case 'K':
+				dontuseprocfs=1;
+				break;
+			case 'l':
+				parsefmt(lfmt);
+				fmt = 1;
+				lfmt[0] = '\0';
+				break;
+			case 'L':
+				showkey();
+				exit(0);
+				/* NOTREACHED */
+			case 'm':
+				sortby = SORTMEM;
+				break;
+			case 'M':
+				memf = optarg;
+				dontuseprocfs = 1;
+				break;
+			case 'N':
+				nlistf = optarg;
+				break;
+			case 'o':
+				parsefmt(optarg);
+				fmt = 1;
+				break;
+			case 'O':
+				parsefmt(o1);
+				parsefmt(optarg);
+				parsefmt(o2);
+				o1[0] = o2[0] = '\0';
+				fmt = 1;
+				break;
+			case 'p':
+				what = KERN_PROC_PID;
+				flag = atol(optarg);
+				noctty = 1;
+				break;
+			case 'r':
+				sortby = SORTCPU;
+				break;
+			case 'S':
+				sumrusage = 1;
+				break;
+			case 't':
+				ttname = optarg;
+			tty: {
+				struct stat sb;
+				char *ttypath, pathbuf[MAXPATHLEN];
+
+				flag = 0;
+				if (strcmp(ttname, "?") == 0)
+					flag = KERN_PROC_TTY_NODEV;
+				else if (strcmp(ttname, "-") == 0)
+					flag = KERN_PROC_TTY_REVOKE;
+				else if (strcmp(ttname, "co") == 0)
+					ttypath = _PATH_CONSOLE;
+				else if (*ttname != '/')
+					(void)snprintf(ttypath = pathbuf,
+					    sizeof(pathbuf), "%s%s", _PATH_TTY, ttname);
+				else
+					ttypath = ttname;
+				what = KERN_PROC_TTY;
+				if (flag == 0) {
+					if (stat(ttypath, &sb) == -1)
+						err(1, "%s", ttypath);
+					if (!S_ISCHR(sb.st_mode))
+						errx(1, "%s: not a terminal", ttypath);
+					flag = sb.st_rdev;
+				}
+				break;
+			}
+			case 'T':
+				if ((ttname = ttyname(STDIN_FILENO)) == NULL)
+					errx(1, "stdin: not a terminal");
+				goto tty;
+			case 'u':
+				parsefmt(ufmt);
+				sortby = SORTCPU;
+				fmt = 1;
+				ufmt[0] = '\0';
+				break;
+			case 'U':
+				if (*optarg != '\0') {
+					struct passwd *pw;
+					char *ep;
+
+					what = KERN_PROC_UID;
+					pw = getpwnam(optarg);
+					if (pw == NULL) {
+						errno = 0;
+						flag = strtoul(optarg, &ep, 10);
+						if (errno)
+							err(1, "%s", optarg);
+						if (*ep != '\0')
+							errx(1, "%s: illegal user name",
+							    optarg);
+					} else
+						flag = pw->pw_uid;
+				}
+				break;
+			case 'v':
+				parsefmt(vfmt);
+				sortby = SORTMEM;
+				fmt = 1;
+				vfmt[0] = '\0';
+				break;
+			case 'w':
+				if (widthflag)
+					termwidth = UNLIMITED;
+				else if (termwidth < 131)
+					termwidth = 131;
+				widthflag++;
+				break;
+			case 'W':
+				swapf = optarg;
+				break;
+			case 'x':
+				noctty = 1;
+				break;
+			default:
+				usage();
+			}
+		if (!fmt)
+			parsefmt(dfmt);
+	}
 	argc -= optind;
 	argv += optind;
 
@@ -355,14 +1095,6 @@ main(argc, argv)
 		}
 	}
 
-	if (!fmt)
-		parsefmt(dfmt);
-
-	/*
-	 * scan requested variables, noting what structures are needed.
-	 */
-	scanvars();
-
 	/*
 	 * select procs
 	 */
@@ -406,7 +1138,7 @@ main(argc, argv)
 		for (i = 0; i < nentries; i++) {
 			struct kinfo_proc2 *ki = &kinfo[i];
 
-			if (xflg == 0 && (ki->p_tdev == NODEV ||
+			if (noctty == 0 && (ki->p_tdev == NODEV ||
 			    (ki->p_flag & P_CONTROLT) == 0))
 				continue;
 			for (vent = vhead; vent; vent = vent->next)
@@ -425,9 +1157,11 @@ main(argc, argv)
 	for (i = lineno = 0; i < nentries; i++) {
 		struct kinfo_proc2 *ki = &kinfo[i];
 
-		if (xflg == 0 && (ki->p_tdev == NODEV ||
+		if (noctty == 0 && (ki->p_tdev == NODEV ||
 		    (ki->p_flag & P_CONTROLT ) == 0))
 			continue;
+		if (nosl && (ki->p_pid == ki->p_sid))
+			continue;
 		for (vent = vhead; vent; vent = vent->next) {
 			(vent->var->oproc)(ki, vent, mode);
 			if (vent->next != NULL)
@@ -451,19 +1185,6 @@ getkinfo_kvm(kd, what, flag, nentriesp)
 {
 	return (kvm_getproc2(kd, what, flag, sizeof(struct kinfo_proc2),
 	    nentriesp));
-}
-
-static void
-scanvars()
-{
-	struct varent *vent;
-	VAR *v;
-
-	for (vent = vhead; vent; vent = vent->next) {
-		v = vent->var;
-		if (v->flag & COMM)
-			needcomm = 1;
-	}
 }
 
 static int
Index: ps.h
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/ps.h,v
retrieving revision 1.17
diff -p -u -r1.17 ps.h
--- ps.h	2000/06/07 04:58:02	1.17
+++ ps.h	2000/06/11 17:47:08
@@ -55,7 +55,7 @@ typedef struct var {
 	char	*name;		/* name(s) of variable */
 	char	*header;	/* default header */
 	char	*alias;		/* aliases */
-#define	COMM	0x01		/* needs exec arguments and environment (XXX) */
+#define	COMM	0x01		/* command only, not args */
 #define	LJUST	0x02		/* left adjust on output (trailing blanks) */
 #define	INF127	0x04		/* 127 = infinity: if > 127, print 127. */
 	u_int	flag;