From nobody Mon Apr 28 12:23:32 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4ZmN046F09z5vJ0V; Mon, 28 Apr 2025 12:23:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ZmN041ZfKz3g7S; Mon, 28 Apr 2025 12:23:32 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1745843012; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4KrA/DppfVAtc6pb0PZXJo24X5Dc1nTBOSflqPH+S8I=; b=DCKSKMB3AWwIJ2tsVOyVXM/l5wtmSls0q18yNkhL2KhwUmPvSsQ0MIodf46SsVQGhwbmPB jfm61iRS/L507CCI/BaEHpZjAfr1lM6cxcX0UdBSmyzbBZMd9irjc2KFfGP8b9hw15/PUr vjOvvTflDZOeaXgZlWCOR7F6Bo0nHCEN66eU+g+sCN34cgo3S09vFzMNYWAVLW/lt1V9vu Y+7VH0BrR/bUmfbzQc57JoP1urbDrc7dYvj6N5CjqUFs2nrVGwQ3pwHcxJsHDEvH+7P5jy PR3MrAwmbPwnuQNaBBkDrhnh4TnYBCzb+3V7YZdkMez21MG9QUuEV/WvY+HV7A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1745843012; a=rsa-sha256; cv=none; b=M3fN1pEaUhWHH8IxuOKK/KMuaMKT+CwKwYKtYoXWmt1uskJcHQsai2yG4QBxGKzzzzgooq Cwr5ffTSc2u3AZDvZlHwoYNuLTDrjQyCsvn0YBUa/O/P5QztfFGOA7An3/1Qz9cDbaJ+Qq J0dOR1rMn5HQUrg0Ze+VVQWRevD9ux9qg1GW4V1M28sRkvn9MupB/KY3IxkzvphF+n5+eI FcS0vanOFTFguzPChbV1L3wvbtHyiQiugJQjayOG4ix40kFcwhggCaSlV77TFX/p+3yDlO a7ib7MyeZfYMt3ULwgQPUqOZ+OIWl/4v1K2ZNrxYLKfj86p0cqw0zGaI/JmAJw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1745843012; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4KrA/DppfVAtc6pb0PZXJo24X5Dc1nTBOSflqPH+S8I=; b=EzoH8AdcxjUkSeFV+DH+evVMhbADcXn/PEkWJx1HYlq6TBZKR+lsy+rUogq6NigQJVwvy7 2hRNtmQTwq/tOqw4Jd2rpeNL7ok3xXxTtSVxwOnKWj4M8VlX6N7exE3Du8wcGIvfJ4CrG+ ZbD7P/ePWjhp4LOZWVzrLy+3w21UP9bX7JgRE3GxqHOVWino479w24wrnie/r3vbWXF/rX I7OfPv6CTppVo5H8CpZuYZtpwfcCtegZbwdzQcgyN8fQioyCMIXS8ZehA1M4+uRXSuf+Gy 9kp4xcUk8ojHOHw5dxWVHdlWvQlw+TyTmvH2c5i0n+l8ap3r+z5WEsBSwW44LQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4ZmN041BCKzbhH; Mon, 28 Apr 2025 12:23:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 53SCNW9t025508; Mon, 28 Apr 2025 12:23:32 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 53SCNWCf025505; Mon, 28 Apr 2025 12:23:32 GMT (envelope-from git) Date: Mon, 28 Apr 2025 12:23:32 GMT Message-Id: <202504281223.53SCNWCf025505@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Olivier Certner Subject: git: 5dad61d9b949 - main - ps(1): Make '-O' more versatile and predictable List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: olce X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5dad61d9b949bb859450266c6accebc106f50fcc Auto-Submitted: auto-generated The branch main has been updated by olce: URL: https://cgit.FreeBSD.org/src/commit/?id=5dad61d9b949bb859450266c6accebc106f50fcc commit 5dad61d9b949bb859450266c6accebc106f50fcc Author: Olivier Certner AuthorDate: 2025-03-07 10:50:46 +0000 Commit: Olivier Certner CommitDate: 2025-04-28 11:58:47 +0000 ps(1): Make '-O' more versatile and predictable The ps(1) display's list of columns is now first built without taking into account the '-O' options. In a second step, all columns passed via '-O' are finally inserted after the built-so-far display's first PID column (if it exists, else at start), in their order of appearance as arguments to the '-O' options. This new two-step procedure suppresses the following undesirable behaviors: - '-O' used to insert the columns of the default display even if the user also passed other options to request specific columns. - Each occurence of '-O' beyond the first would just insert the passed keywords after those requested by the previous options, as if by '-o', inconsistently with the behavior for the first occurence. These behaviors had more annoying consequences: - Where the columns of some '-O' occurence appear in the display used to depend on the actual position of '-O' with respect to other options, despite the natural expectation that they should go near a single PID column considered as an anchor regardless of other options adding columns. - Columns specified with multiple '-O' options would not be grouped together. - It used to be impossible to specify custom headers but for the last column for columns that are next to each other (i.e., specified by a single '-O' occurence). which are now all lifted. With these changes, '-O' can still be used alone to amend the default display, but can now be used also in conjunction with any specific display, and in particular "canned" ones invoked by '-j', '-l', '-u' or '-v'. ****** This part discusses other ps(1) implementations' behaviors and compares them to the one established by this change. NetBSD seems to be the only other BSD having refined the meaning of ps(1)'s '-O' option. While the behavior there is similar to the new one here on the surface, it differs on the following points: 1. If no options requesting a specific display are present before the first '-O' option, the appearance of '-O' triggers the insertion of the default display, regardless of whether such specific display options appear *after* it. 2. If options requesting a specific display appear before the first '-O' and none specify a PID column, columns listed in the first '-O' are appended to them (as '-o' would do), but columns passed by further '-O' options are then inserted next to the columns of the first '-O' options. Behavior of point 1 seems to have only one advantage: To allow to customize the default display by first using '-O' and then other options appending to it, but as the default display finishes with the COMMAND column, it is unlikely that one wants to use '-o' or other specific display options after '-O' (NetBSD's ps(1) does not suppress duplicate columns). A much simpler and easy-to-understand way to reach that effect in FreeBSD, if it really proves useful, would be to introduce a new explicit option that inserts the default display. The column-appending behavior of the first '-O' option in point 2 can be also achieved by using '-o' instead. As '-O' is used to insert columns after the PID one, which is located near the left in the default and all "canned" displays, we found it more consistent and practical to push its columns completely to the left on the absence of a PID column. The effect of multiple '-O' options in NetBSD when no PID column has been requested beforehand is also cumbersome and inconsistent with the documentation (it is likely a bug). Both NetBSD-specific behaviors exposed above also have the disadvantage that the position of '-O' options with respect to other ones is meaningful in ways that are not obvious and that are arguably not desirable as '-O' is meant to append columns after an anchor (the PID column). Linux's procps-ng's ps(1) is very limited in its handling of '-O', and more generally when mixing options tweaking the display. '-O' causes insertion of the default display (like NetBSD does). If '-o' options are specified, '-O' must come before them. '-O' is not usable with canned display options. Additionally, only one '-O' option may appear on the command line, limiting header customization. The only case in which these implementations and ours behave in the same way with respect to '-O' is if only a single '-O' option and no other options changing the display are specified. MFC after: 3 days Relnotes: yes Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D49615 (code) Differential Revision: https://reviews.freebsd.org/D49616 (manual page) --- bin/ps/ps.1 | 31 ++++++++++--------------------- bin/ps/ps.c | 28 ++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/bin/ps/ps.1 b/bin/ps/ps.1 index 801b089820c7..2e25249c2e76 100644 --- a/bin/ps/ps.1 +++ b/bin/ps/ps.1 @@ -125,9 +125,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. @@ -327,15 +325,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 0a4a289a6a63..48839cd00837 100644 --- a/bin/ps/ps.c +++ b/bin/ps/ps.c @@ -96,6 +96,7 @@ struct keyword_info { }; struct velisthead varlist = STAILQ_HEAD_INITIALIZER(varlist); +static struct velisthead Ovarlist = STAILQ_HEAD_INITIALIZER(Ovarlist); static kvm_t *kd; static int needcomm; /* -o "command" */ @@ -151,8 +152,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"; @@ -334,10 +333,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); @@ -471,6 +467,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");