git: 158c59210d95 - main - sysconf: report a truncated keyword match list

From: Devin Teske <dteske_at_FreeBSD.org>
Date: Sun, 18 Oct 2026 15:46:57 UTC
The branch main has been updated by dteske:

URL: https://cgit.FreeBSD.org/src/commit/?id=158c59210d9530af64b2bd6a08c7ffd216b243a8

commit 158c59210d9530af64b2bd6a08c7ffd216b243a8
Author:     Devin Teske <dteske@FreeBSD.org>
AuthorDate: 2026-10-18 15:43:37 +0000
Commit:     Devin Teske <dteske@FreeBSD.org>
CommitDate: 2026-10-18 15:43:37 +0000

    sysconf: report a truncated keyword match list
    
    snprintf(3) returns the length that would have been written, so an
    ambiguous prefix can fill the match buffer with no sign that names
    were cut off.  Append " (truncated)" when that happens.  Drop the
    empty statement when scanning option arguments: only a separate
    argument consumes the next argv entry.
    
    Bump sysconf(8) to 2.2.1.
    
    Suggested by:   fuz
    Reviewed by:    fuz
    Differential Revision:  https://reviews.freebsd.org/D60815
---
 usr.sbin/sysconf/sysconf-targets.c | 20 +++++++++++++-------
 usr.sbin/sysconf/sysconf_priv.h    |  2 +-
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/usr.sbin/sysconf/sysconf-targets.c b/usr.sbin/sysconf/sysconf-targets.c
index 9031b6c06748..94b616db9b93 100644
--- a/usr.sbin/sysconf/sysconf-targets.c
+++ b/usr.sbin/sysconf/sysconf-targets.c
@@ -70,7 +70,13 @@ resolve_keyword(const char *token, const char *const *keywords,
 	if (nmatch == 1)
 		return (found);
 	if (nmatch > 1) {
-		warnx("ambiguous %s `%s'; matches %s", what, token, matches);
+		/*
+		 * snprintf(3) returns the length that would have been
+		 * written, so off >= sizeof(matches) means the list was
+		 * truncated.
+		 */
+		warnx("ambiguous %s `%s'; matches %s%s", what, token, matches,
+		    off >= sizeof(matches) ? " (truncated)" : "");
 		usage();
 	}
 	return (NULL);
@@ -127,14 +133,14 @@ find_operand(int argc, char *argv[], int from, int past_dd)
 			}
 			for (p = argv[n] + 1; *p != '\0'; p++) {
 				o = strchr(OPTSTRING, *p);
+				/* Does the option take an argument? */
 				if (o != NULL && o[1] == ':') {
-					/* Takes an argument */
-					if (p[1] != '\0') {
-						;
-						/* attached: rest of argv[n] */
-					} else if (n + 1 < argc) {
+					/*
+					 * Is the option argument in the next
+					 * argv entry?
+					 */
+					if (p[1] == '\0' && n + 1 < argc) {
 						n++;
-						/* separate argv */
 					}
 					break;
 				}
diff --git a/usr.sbin/sysconf/sysconf_priv.h b/usr.sbin/sysconf/sysconf_priv.h
index a2d9190df284..1037c422d0ed 100644
--- a/usr.sbin/sysconf/sysconf_priv.h
+++ b/usr.sbin/sysconf/sysconf_priv.h
@@ -37,7 +37,7 @@
 #define __unused	/* not all compilers support attributes */
 #endif
 
-#define SYSCONF_VERSION	"2.2 2026-09-22"
+#define SYSCONF_VERSION	"2.2.1 2026-10-17"
 
 /* getopt(3) optstring; shared by parse_options() and find_target() */
 #define OPTSTRING	"AacdDEeFf:hij:k:lLnNqR:svVx"