diff --git a/bin/ps/ps.1 b/bin/ps/ps.1 index e3681a5641c..d823df48c09 100644 --- a/bin/ps/ps.1 +++ b/bin/ps/ps.1 @@ -127,9 +127,7 @@ First, options .Fl o and .Fl O -add columns with data corresponding to the explicitly passed keywords and, for -.Fl O , -additionally the same columns as in the default display. +add columns with data corresponding to the explicitly passed keywords. Available keywords are documented in the .Sx KEYWORDS section below. @@ -323,15 +321,15 @@ terminal and process ID. Extract the name list from the specified system instead of the default, which is the kernel image the system has booted from. .It Fl O -On first occurence, add all columns of the default display -.Po -as if by -.Fl o -.Pc -and insert just after the process ID column in that default display the columns -associated with the passed space- or comma-separated list of keywords. -On next occurences, just insert the keywords of the passed list, as if by -.Fl o . +Save passed columns in a separate list that in the end is grafted just after the +display's first occurence of the process ID column as specified by other +options, or the default display if there is none. +If the display prepared by other options does not include a process ID column, +the list is inserted at start of the display. +Further occurences of +.Fl O +append to the to-be-grafted list of columns. +This option takes a space- or comma-separated list of keywords. The last keyword in the list may be appended with an equals sign .Pq Ql = as explained for option @@ -1023,15 +1021,6 @@ implementation (for other BSDs, illumos or Linux) behaves like this. For all these reasons, the behavior is expected to be changed soon to using the effective user ID instead. .Pp -Option -.Fl O -has not been designed to be combined with other options as it forces insertion -of the default display on first occurence. -Moreover, these default display's columns are then not considered for duplicate -elimination, contrary to those of canned displays. -Finally, columns requested through multiple occurences are not grouped together, -as one may naturally expect. -.Pp The .Fl a option has no effect if other options affecting the selection of processes are diff --git a/bin/ps/ps.c b/bin/ps/ps.c index 03454cb2b6e..db339a76598 100644 --- a/bin/ps/ps.c +++ b/bin/ps/ps.c @@ -117,6 +117,7 @@ struct keyword_info { }; struct velisthead varlist = STAILQ_HEAD_INITIALIZER(varlist); +static struct velisthead Ovarlist = STAILQ_HEAD_INITIALIZER(Ovarlist); static int forceuread = DEF_UREAD; /* Do extra work to get u-area. */ static kvm_t *kd; @@ -173,8 +174,6 @@ static const char dfmt[] = "pid,tt,state,time,command"; static const char jfmt[] = "user,pid,ppid,pgid,sid,jobc,state,tt,time,command"; static const char lfmt[] = "uid,pid,ppid,cpu,pri,nice,vsz,rss,mwchan,state," "tt,time,command"; -static const char o1[] = "pid"; -static const char o2[] = "tt,state,time,command"; static const char ufmt[] = "user,pid,%cpu,%mem,vsz,rss,tt,state,start,time,command"; static const char vfmt[] = "pid,state,time,sl,re,pagein,vsz,rss,lim,tsiz," "%cpu,%mem,command"; @@ -359,10 +358,7 @@ main(int argc, char *argv[]) nlistf = optarg; break; case 'O': - parsefmt(o1, &varlist, 1); - parsefmt(optarg, &varlist, 1); - parsefmt(o2, &varlist, 1); - _fmt = 1; + parsefmt(optarg, &Ovarlist, 1); break; case 'o': parsefmt(optarg, &varlist, 1); @@ -496,6 +492,26 @@ main(int argc, char *argv[]) if (!_fmt) parsefmt(dfmt, &varlist, 0); + if (!STAILQ_EMPTY(&Ovarlist)) { + VARENT *const pid_entry = find_varentry("pid"); + + /* + * We insert the keywords passed by '-O' after the process ID if + * specified, else at start. + */ + if (pid_entry != NULL) { + struct velisthead rest; + + STAILQ_SPLIT_AFTER(&varlist, pid_entry, &rest, next_ve); + STAILQ_CONCAT(&varlist, &Ovarlist); + STAILQ_CONCAT(&varlist, &rest); + } + else { + STAILQ_SWAP(&varlist, &Ovarlist, varent); + STAILQ_CONCAT(&varlist, &Ovarlist); + } + } + keywords_info = calloc(known_keywords_nb, sizeof(struct keyword_info)); if (keywords_info == NULL) xo_errx(1, "malloc failed");