git: b2bf651a797b - main - sockstat: Reintroduce -w flag with altered behavior

From: Alan Somers <asomers_at_FreeBSD.org>
Date: Tue, 15 Jul 2025 21:09:48 UTC
The branch main has been updated by asomers:

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

commit b2bf651a797b7bf177146d497e59ab86e4898f6d
Author:     Damin Rido <daminrido139@gmail.com>
AuthorDate: 2025-06-30 13:46:28 +0000
Commit:     Alan Somers <asomers@FreeBSD.org>
CommitDate: 2025-07-15 21:09:02 +0000

    sockstat: Reintroduce -w flag with altered behavior
    
    The -w flag was previously removed when automatic column sizing was
    introduced. Originally, -w enabled wider output, but used hardcoded
    column widths that did not guarantee alignment with actual content.
    
    This commit reintroduces the -w flag with a new purpose: to dynamically
    size columns based on the longest entry in the current output.  Unlike
    the original behavior, this version ensures fully aligned and
    consistently formatted rows.
    
    By default, sockstat now uses fixed-width columns for more compact
    output, especially in 80-column terminals. Users who prefer a full-width
    view can now use -w to enable automatic column sizing.
    
    Sponsored by:   Google, LLC (GSoC 2025)
    MFC after:      2 weeks
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1746
    Reviewed by:    asomers, glebius
---
 usr.bin/sockstat/sockstat.1 |  6 ++--
 usr.bin/sockstat/sockstat.c | 74 +++++++++++++++++++++++----------------------
 2 files changed, 42 insertions(+), 38 deletions(-)

diff --git a/usr.bin/sockstat/sockstat.1 b/usr.bin/sockstat/sockstat.1
index da658e33e542..4832a09764fd 100644
--- a/usr.bin/sockstat/sockstat.1
+++ b/usr.bin/sockstat/sockstat.1
@@ -25,7 +25,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 27, 2025
+.Dd June 30, 2025
 .Dt SOCKSTAT 1
 .Os
 .Sh NAME
@@ -33,7 +33,7 @@
 .Nd list open sockets
 .Sh SYNOPSIS
 .Nm
-.Op Fl 46ACcfIiLlnqSsUuv
+.Op Fl 46ACcfIiLlnqSsUuvw
 .Op Fl j Ar jail
 .Op Fl p Ar ports
 .Op Fl P Ar protocols
@@ -119,6 +119,8 @@ Show
 sockets.
 .It Fl v
 Verbose mode.
+.It Fl w
+Automatically size the columns.
 .El
 .Pp
 If neither
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index 1a24ff67c321..d0540c54a1aa 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -97,6 +97,7 @@ static bool	 opt_s;		/* Show protocol state if applicable */
 static bool	 opt_U;		/* Show remote UDP encapsulation port number */
 static bool	 opt_u;		/* Show Unix domain sockets */
 static u_int	 opt_v;		/* Verbose mode */
+static bool	 opt_w;		/* Automatically size the columns */
 
 /*
  * Default protocols to use if no -P was defined.
@@ -1101,7 +1102,7 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
 	/* Remote peer we connect(2) to, if any. */
 	if (faddr->conn != 0) {
 		struct sock *p;
-		pos += strlcpy(buf, "-> ", bufsize);
+		pos += strlcpy(SAFEBUF, "-> ", SAFESIZE);
 		p = RB_FIND(pcbs_t, &pcbs,
 			&(struct sock){ .pcb = faddr->conn });
 		if (__predict_false(p == NULL)) {
@@ -1132,8 +1133,7 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
 		while ((p = RB_FIND(pcbs_t, &pcbs,
 			&(struct sock){ .pcb = ref })) != 0) {
 			f = RB_FIND(files_t, &ftree,
-				&(struct file){ .xf_data =
-				p->socket });
+				&(struct file){ .xf_data = p->socket });
 			if (f != NULL) {
 				pos += snprintf(SAFEBUF, SAFESIZE,
 					"%s[%lu %d]", fref ? "" : ",",
@@ -1178,13 +1178,10 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
 	len = strlen(s->protoname);
 	if (s->vflag & (INP_IPV4 | INP_IPV6))
 		len += 1;
-	if (laddr != NULL && faddr != NULL && s->family == AF_UNIX &&
-		laddr->address.ss_len == 0 && faddr->conn == 0)
-		len += strlen(" (not connected)");
 	cw->proto = MAX(cw->proto, len);
 
 	while (laddr != NULL || faddr != NULL) {
-		if (s->family == AF_UNIX) {
+		if (opt_w && s->family == AF_UNIX) {
 			if ((laddr == NULL) || (faddr == NULL))
 				errx(1, "laddr = %p or faddr = %p is NULL",
 					(void *)laddr, (void *)faddr);
@@ -1193,7 +1190,7 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
 			cw->local_addr = MAX(cw->local_addr, len);
 			len = format_unix_faddr(faddr, NULL, 0);
 			cw->foreign_addr = MAX(cw->foreign_addr, len);
-		} else {
+		} else if (opt_w) {
 			if (laddr != NULL) {
 				len = formataddr(&laddr->address, NULL, 0);
 				cw->local_addr = MAX(cw->local_addr, len);
@@ -1296,23 +1293,6 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
 static void
 calculate_column_widths(struct col_widths *cw)
 {
-	cw->user = 4;
-	cw->command = 10;
-	cw->pid = 3;
-	cw->fd = 2;
-	cw->proto = 5;
-	cw->local_addr = 13;
-	cw->foreign_addr = 15;
-	cw->pcb_kva = 18;
-	cw->fib = 3;
-	cw->splice_address = 14;
-	cw->inp_gencnt = 2;
-	cw->encaps = 6;
-	cw->path_state = 10;
-	cw->conn_state = 10;
-	cw->stack = 5;
-	cw->cc = 2;
-
 	int n, len;
 	struct file *xf;
 	struct sock *s;
@@ -1366,13 +1346,10 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
 	faddr = s->faddr;
 	first = true;
 
-	snprintf(buf, bufsize, "%s%s%s%s",
+	snprintf(buf, bufsize, "%s%s%s",
 		s->protoname,
 		s->vflag & INP_IPV4 ? "4" : "",
-		s->vflag & INP_IPV6 ? "6" : "",
-		(laddr != NULL && faddr != NULL &&
-		s->family == AF_UNIX && laddr->address.ss_len == 0 &&
-		faddr->conn == 0) ? " (not connected)" : "");
+		s->vflag & INP_IPV6 ? "6" : "");
 	printf(" %-*s", cw->proto, buf);
 	while (laddr != NULL || faddr != NULL) {
 		if (s->family == AF_UNIX) {
@@ -1381,23 +1358,27 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
 					(void *)laddr, (void *)faddr);
 			if (laddr->address.ss_len > 0)
 				formataddr(&laddr->address, buf, bufsize);
+			else if (laddr->address.ss_len == 0 && faddr->conn == 0)
+				strlcpy(buf, "(not connected)", bufsize);
 			else
 				strlcpy(buf, "??", bufsize);
-			printf(" %-*s", cw->local_addr, buf);
+			printf(" %-*.*s", cw->local_addr, cw->local_addr, buf);
 			if (format_unix_faddr(faddr, buf, bufsize) == 0)
 				strlcpy(buf, "??", bufsize);
-			printf(" %-*s", cw->foreign_addr, buf);
+			printf(" %-*.*s", cw->foreign_addr,
+				cw->foreign_addr, buf);
 		} else {
 			if (laddr != NULL)
 				formataddr(&laddr->address, buf, bufsize);
 			else
 				strlcpy(buf, "??", bufsize);
-			printf(" %-*s", cw->local_addr, buf);
+			printf(" %-*.*s", cw->local_addr, cw->local_addr, buf);
 			if (faddr != NULL)
 				formataddr(&faddr->address, buf, bufsize);
 			else
 				strlcpy(buf, "??", bufsize);
-			printf(" %-*s", cw->foreign_addr, buf);
+			printf(" %-*.*s", cw->foreign_addr,
+				cw->foreign_addr, buf);
 		}
 		if (opt_A)
 			printf(" %#*" PRIx64, cw->pcb_kva, s->pcb);
@@ -1411,6 +1392,8 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
 				if (sp != NULL)
 					formataddr(&sp->laddr->address,
 								buf, bufsize);
+				else
+					strlcpy(buf, "??", bufsize);
 			} else
 				strlcpy(buf, "??", bufsize);
 			printf(" %-*s", cw->splice_address, buf);
@@ -1510,6 +1493,25 @@ display(void)
 		err(1, "malloc()");
 		return;
 	}
+
+	cw = (struct col_widths) {
+		.user = strlen("USER"),
+		.command = 10,
+		.pid = strlen("PID"),
+		.fd = strlen("FD"),
+		.proto = strlen("PROTO"),
+		.local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21,
+		.foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21,
+		.pcb_kva = 18,
+		.fib = strlen("FIB"),
+		.splice_address = strlen("SPLICE ADDRESS"),
+		.inp_gencnt = strlen("ID"),
+		.encaps = strlen("ENCAPS"),
+		.path_state = strlen("PATH STATE"),
+		.conn_state = strlen("CONN STATE"),
+		.stack = strlen("STACK"),
+		.cc = strlen("CC"),
+	};
 	calculate_column_widths(&cw);
 
 	if (!opt_q) {
@@ -1642,7 +1644,7 @@ static void
 usage(void)
 {
 	errx(1,
-    "usage: sockstat [-46ACcfIiLlnqSsUuv] [-j jid] [-p ports] [-P protocols]");
+    "usage: sockstat [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]");
 }
 
 int
@@ -1721,7 +1723,7 @@ main(int argc, char *argv[])
 			++opt_v;
 			break;
 		case 'w':
-			/* left for backward compatibility. */
+			opt_w = true;
 			break;
 		default:
 			usage();