Subject: Re: ps -o field=HEADING,field2=HEADING2
To: None <tech-userlevel@NetBSD.org>
From: Alan Barrett <apb@cequrux.com>
List: tech-userlevel
Date: 10/01/2006 23:17:18
On Mon, 11 Sep 2006, Alan Barrett wrote:
> Several issues with ps:

I intend to commit the changes in
<ftp://ftp.netbsd.org/pub/NetBSD/misc/apb/ps.20061001.diff> soon.

> 1) SUSv2 says that {ps -o "field1=HEADING1,field2=HEADING2"} specifies
> only one field: field1, whose heading is "HEADING1,field2=HEADING2".
> NetBSD's ps thinks that it specifies two fields: field1 with heading
> "HEADING1", and field2 with heading "HEADING2".  I think we should
> change to be SUS compatible here.  Any objections?

P1004.1-2004 (SUSv3) says the same thing.  My patch changes the existing
behaviour; if you previously used {ps -o foo=FOO,bar=BAR} expecting it
to treat foo and bar as two separate keywords, then you will need to
change to {ps -o foo=FOO -o bar=BAR}.  The new code treats everything
after the first "=" as part of the customised header, and this may
include embedded spaces, commas, or equals signs.

> 2) SUSv2 says that, if all the fields have null headings, then no
> heading is printed at all.  For example, {ps -p ${pid} -o "command="}
> should print just one line with the command associated with the
>> specified process.  NetBSD's ps prints a header line containing zero or
> more spaces in this case.  I think we should be SUS compatible here, and
> I have already fixed this in my working tree.  Any objections?

My patch changes this.

> 3) Multiple -O options don't work as expected.  {ps -O %mem -O %cpu}
> puts the %mem column in the right place (just after the pid column), but
> puts the %cpu column at the end.  In contrast, {ps -O %mem,%cpu} works
> as I expected.  Any objections to changing this?

I changed the way -O works.  The new behaviour is:  If the default format
hasn't been overridden (via -o, -j, -l, -s, or -u) before the first -O flag
is encountered, then the default format is implicitly added before the extra
fields specified by the -O flag are added; but if the default has been
overridden, then the default fields are not added again.  Then the format is
searched for a "pid" column, and if it is found, the -O keywords are inserted
just after the pid column, but if there is no pod column, then the -O
keywords are appended to the format.  Subsequent -O options after the first
will be inserted just after the position used by the previous -O option.

For example, {ps -j -O %cpu} previously displayed these columns: "USER
PID PPID PGID SESS JOBC STAT TTY TIME COMMAND PID %CPU TTY STAT TIME
COMMAND" (all the columns requested by "-j", followed by all the columns
in the default format, with "%CPU" inserted just after the "PID" column
in the default format.  After my changes, {ps -j -O %cpu} will display
these columns:  "USER PID %CPU PPID PGID SESS JOBC STAT TTY TIME
COMMAND" (the columns requested by "-j", with "%CPU" inserted just after
"PID").

> 4) If you try to print a column multiple times with different headings,
> the last heading is used for all copies.  For example, try {ps -o
> pid=AAA -o pid=BBB}.

Fixed.

> 5) The Coverity "fix" in revision 1.46 of keyword.c is wrong.  The
> allocated memory can't be freed, because the field list might contain
> pointers into it.  (For example, try {ps -o ppid= -p $$} to see the
> result of keeping a pointer to freed memory.)  I just reverted that
> change in my working tree, but perhaps somebody has a better fix.
> Note that fixing issue 4 above will also affect this.

Fixed.

> 6) When I commit whatever fixes I make, I will include regression
> tests.

Done.  The regression tests apply only to the column order and headers,
not to the real functionality.

--apb (Alan Barrett)