git: 9006a731bc95 - main - /bin/ps: Fix display of negative nice values on ARMv7/aarch64

From: Warner Losh <imp_at_FreeBSD.org>
Date: Sat, 07 Mar 2026 07:51:18 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=9006a731bc951c5b62efc4bf75a0c5b42586d279

commit 9006a731bc951c5b62efc4bf75a0c5b42586d279
Author:     Jamie Landeg-Jones <jamie@catflap.org>
AuthorDate: 2026-03-07 01:18:20 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-03-07 07:51:14 +0000

    /bin/ps: Fix display of negative nice values on ARMv7/aarch64
    
    On Arm-based systems (and maybe others), 'char' defaults to unsigned,
    causing negative nice values to be displayed incorrectly (e.g., 246
    instead of -10). Explicitly using 'signed char' ensures consistent
    behaviour across architectures.
    
    [ tested on RPI2 and generic aarch64 qemu install ]
    
    Before:
      # /usr/bin/nice --10 ps -l | awk '(NR == 1 || $(NF-1) == "ps")'
      UID   PID  PPID C PRI  NI  VSZ  RSS MWCHAN  STAT TT     TIME COMMAND
        0 23606 22800 2 -32 246 5400 2544 -       R<+   0  0:00.06 ps -l
    
    After:
      # /usr/bin/nice --10 ps -l | awk '(NR == 1 || $(NF-1) == "ps")'
      UID   PID  PPID C PRI  NI  VSZ  RSS MWCHAN  STAT TT     TIME COMMAND
        0 23614 22800 3 -32 -10 5400 2544 -       R<+   0  0:00.05 ps -l
    
    Signed-off-by: Jamie Landeg-Jones <jamie@catflap.org>
    Reviewed by: imp
    Pull Request: https://github.com/freebsd/freebsd-src/pull/2064
---
 bin/ps/keyword.c | 2 +-
 bin/ps/print.c   | 3 +++
 bin/ps/ps.h      | 2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c
index 0562fd2e4f9d..d7790f9f8c48 100644
--- a/bin/ps/keyword.c
+++ b/bin/ps/keyword.c
@@ -133,7 +133,7 @@ static VAR keywords[] = {
 	{"mwchan", {NULL}, "MWCHAN", "wait-channel", LJUST, mwchan, 0,
 	 UNSPEC, NULL},
 	{"ni", {"nice"}, NULL, NULL, 0, NULL, 0, UNSPEC, NULL},
-	{"nice", {NULL}, "NI", "nice", 0, kvar, KOFF(ki_nice), CHAR, "d"},
+	{"nice", {NULL}, "NI", "nice", 0, kvar, KOFF(ki_nice), SCHAR, "d"},
 	{"nivcsw", {NULL}, "NIVCSW", "involuntary-context-switches", USER, rvar,
 	 ROFF(ru_nivcsw), LONG, "ld"},
 	{"nlwp", {NULL}, "NLWP", "threads", 0, kvar, KOFF(ki_numthreads),
diff --git a/bin/ps/print.c b/bin/ps/print.c
index f59e843effc1..9705d0c07419 100644
--- a/bin/ps/print.c
+++ b/bin/ps/print.c
@@ -754,6 +754,9 @@ printval(void *bp, const VAR *v)
 	case CHAR:
 		(void)asprintf(&str, ofmt, *(char *)bp);
 		break;
+	case SCHAR:
+		(void)asprintf(&str, ofmt, *(signed char *)bp);
+		break;
 	case UCHAR:
 		(void)asprintf(&str, ofmt, *(u_char *)bp);
 		break;
diff --git a/bin/ps/ps.h b/bin/ps/ps.h
index 065a4c1f1c54..8352f3450f93 100644
--- a/bin/ps/ps.h
+++ b/bin/ps/ps.h
@@ -33,7 +33,7 @@
 
 #define	UNLIMITED	0	/* unlimited terminal width */
 enum type { UNSPEC, /* For output routines that don't care and aliases. */
-	    CHAR, UCHAR, SHORT, USHORT, INT, UINT, LONG, ULONG, KPTR, PGTOK };
+	    CHAR, SCHAR, UCHAR, SHORT, USHORT, INT, UINT, LONG, ULONG, KPTR, PGTOK };
 
 typedef struct kinfo_str {
 	STAILQ_ENTRY(kinfo_str) ks_next;