git: 0726c6574f88 - main - sockstat: Add automatic column sizing and remove -w option
Date: Fri, 27 Jun 2025 15:59:32 UTC
The branch main has been updated by asomers:
URL: https://cgit.FreeBSD.org/src/commit/?id=0726c6574f889507e5030173bf4c82c80911394d
commit 0726c6574f889507e5030173bf4c82c80911394d
Author: Damin Rido <rido@FreeBSD.com>
AuthorDate: 2025-06-12 09:12:49 +0000
Commit: Alan Somers <asomers@FreeBSD.org>
CommitDate: 2025-06-27 15:54:41 +0000
sockstat: Add automatic column sizing and remove -w option
Refactor sockstat to dynamically size table columns based on content.
This eliminates the need for the -w option, which is now ignored
for backwards compatibility.
Numeric columns are now right-aligned for improved readability;
previously, they were left-aligned.
Unknown fields are now consistently shown as "??" instead of a mix
of "", "?", and "?" for output uniformity.
Sponsored by: Google, LLC (GSoC 2025)
MFC after: 2 weeks
Reviewed by: asomers
Pull Request: https://github.com/freebsd/freebsd-src/pull/1720
---
usr.bin/sockstat/sockstat.1 | 6 +-
usr.bin/sockstat/sockstat.c | 622 +++++++++++++++++++++++++++-----------------
2 files changed, 392 insertions(+), 236 deletions(-)
diff --git a/usr.bin/sockstat/sockstat.1 b/usr.bin/sockstat/sockstat.1
index b13c6afdd9c0..da658e33e542 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 February 6, 2025
+.Dd June 27, 2025
.Dt SOCKSTAT 1
.Os
.Sh NAME
@@ -33,7 +33,7 @@
.Nd list open sockets
.Sh SYNOPSIS
.Nm
-.Op Fl 46ACcfIiLlnqSsUuvw
+.Op Fl 46ACcfIiLlnqSsUuv
.Op Fl j Ar jail
.Op Fl p Ar ports
.Op Fl P Ar protocols
@@ -119,8 +119,6 @@ Show
sockets.
.It Fl v
Verbose mode.
-.It Fl w
-Use wider field size for displaying addresses.
.El
.Pp
If neither
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index e1a52c57b3d1..52243910a31c 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -97,7 +97,6 @@ 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; /* Wide print area for addresses */
/*
* Default protocols to use if no -P was defined.
@@ -193,20 +192,6 @@ static cap_channel_t *capnetdb;
static cap_channel_t *capsysctl;
static cap_channel_t *cappwd;
-static int
-xprintf(const char *fmt, ...)
-{
- va_list ap;
- int len;
-
- va_start(ap, fmt);
- len = vprintf(fmt, ap);
- va_end(ap);
- if (len < 0)
- err(1, "printf()");
- return (len);
-}
-
static bool
_check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
{
@@ -941,7 +926,7 @@ getfiles(void)
}
static int
-printaddr(struct sockaddr_storage *ss)
+formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
{
struct sockaddr_un *sun;
char addrstr[NI_MAXHOST] = { '\0', '\0' };
@@ -961,18 +946,18 @@ printaddr(struct sockaddr_storage *ss)
case AF_UNIX:
sun = sstosun(ss);
off = (int)((char *)&sun->sun_path - (char *)sun);
- return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
+ return snprintf(buf, bufsize, "%.*s",
+ sun->sun_len - off, sun->sun_path);
}
if (addrstr[0] == '\0') {
error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
- addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
+ addrstr, sizeof(addrstr), buf, bufsize, NI_NUMERICHOST);
if (error)
errx(1, "cap_getnameinfo()");
}
if (port == 0)
- return xprintf("%s:*", addrstr);
- else
- return xprintf("%s:%d", addrstr, port);
+ return snprintf(buf, bufsize, "%s:*", addrstr);
+ return snprintf(buf, bufsize, "%s:%d", addrstr, port);
}
static const char *
@@ -1107,235 +1092,408 @@ sctp_path_state(int state)
}
}
+static int
+format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
+ #define SAFEBUF (buf == NULL ? NULL : buf + pos)
+ #define SAFESIZE (buf == NULL ? 0 : bufsize - pos)
+
+ size_t pos = 0;
+ /* Remote peer we connect(2) to, if any. */
+ if (faddr->conn != 0) {
+ struct sock *p;
+ pos += strlcpy(buf, "-> ", bufsize);
+ p = RB_FIND(pcbs_t, &pcbs,
+ &(struct sock){ .pcb = faddr->conn });
+ if (__predict_false(p == NULL)) {
+ /* XXGL: can this happen at all? */
+ pos += snprintf(SAFEBUF, SAFESIZE, "??");
+ } else if (p->laddr->address.ss_len == 0) {
+ struct file *f;
+ f = RB_FIND(files_t, &ftree,
+ &(struct file){ .xf_data =
+ p->socket });
+ if (f != NULL) {
+ pos += snprintf(SAFEBUF, SAFESIZE, "[%lu %d]",
+ (u_long)f->xf_pid, f->xf_fd);
+ }
+ } else
+ pos += formataddr(&p->laddr->address,
+ SAFEBUF, SAFESIZE);
+ }
+ /* Remote peer(s) connect(2)ed to us, if any. */
+ if (faddr->firstref != 0) {
+ struct sock *p;
+ struct file *f;
+ kvaddr_t ref = faddr->firstref;
+ bool fref = true;
+
+ pos += snprintf(SAFEBUF, SAFESIZE, " <- ");
+
+ while ((p = RB_FIND(pcbs_t, &pcbs,
+ &(struct sock){ .pcb = ref })) != 0) {
+ f = RB_FIND(files_t, &ftree,
+ &(struct file){ .xf_data =
+ p->socket });
+ if (f != NULL) {
+ pos += snprintf(SAFEBUF, SAFESIZE,
+ "%s[%lu %d]", fref ? "" : ",",
+ (u_long)f->xf_pid, f->xf_fd);
+ }
+ ref = p->faddr->nextref;
+ fref = false;
+ }
+ }
+ return pos;
+}
+
+struct col_widths {
+ int user;
+ int command;
+ int pid;
+ int fd;
+ int proto;
+ int local_addr;
+ int foreign_addr;
+ int pcb_kva;
+ int fib;
+ int splice_address;
+ int inp_gencnt;
+ int encaps;
+ int path_state;
+ int conn_state;
+ int stack;
+ int cc;
+};
+
static void
-displaysock(struct sock *s, int pos)
+calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
{
- int first, offset;
struct addr *laddr, *faddr;
-
- while (pos < 30)
- pos += xprintf(" ");
- pos += xprintf("%s", s->protoname);
- if (s->vflag & INP_IPV4)
- pos += xprintf("4");
- if (s->vflag & INP_IPV6)
- pos += xprintf("6");
- if (s->vflag & (INP_IPV4 | INP_IPV6))
- pos += xprintf(" ");
+ bool first = true;
+ int len = 0;
laddr = s->laddr;
faddr = s->faddr;
- first = 1;
+ first = true;
+
+ 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) {
- offset = 37;
- while (pos < offset)
- pos += xprintf(" ");
- switch (s->family) {
- case AF_INET:
- case AF_INET6:
- if (laddr != NULL)
- pos += printaddr(&laddr->address);
- offset += opt_w ? 46 : 22;
- do
- pos += xprintf(" ");
- while (pos < offset);
- if (faddr != NULL)
- pos += printaddr(&faddr->address);
- offset += opt_w ? 46 : 22;
- break;
- case AF_UNIX:
+ if (s->family == AF_UNIX) {
if ((laddr == NULL) || (faddr == NULL))
errx(1, "laddr = %p or faddr = %p is NULL",
- (void *)laddr, (void *)faddr);
- if (laddr->address.ss_len == 0 && faddr->conn == 0) {
- pos += xprintf("(not connected)");
- offset += opt_w ? 92 : 44;
- break;
- }
- /* Local bind(2) address, if any. */
+ (void *)laddr, (void *)faddr);
if (laddr->address.ss_len > 0)
- pos += printaddr(&laddr->address);
- /* Remote peer we connect(2) to, if any. */
- if (faddr->conn != 0) {
- struct sock *p;
-
- pos += xprintf("%s-> ",
- laddr->address.ss_len > 0 ? " " : "");
- p = RB_FIND(pcbs_t, &pcbs,
- &(struct sock){ .pcb = faddr->conn });
- if (__predict_false(p == NULL)) {
- /* XXGL: can this happen at all? */
- pos += xprintf("??");
- } else if (p->laddr->address.ss_len == 0) {
- struct file *f;
-
- f = RB_FIND(files_t, &ftree,
- &(struct file){ .xf_data =
- p->socket });
- if (f != NULL) {
- pos += xprintf("[%lu %d]",
- (u_long)f->xf_pid,
- f->xf_fd);
- }
- } else
- pos += printaddr(&p->laddr->address);
+ len = formataddr(&laddr->address, NULL, 0);
+ cw->local_addr = MAX(cw->local_addr, len);
+ len = format_unix_faddr(faddr, NULL, 0);
+ cw->foreign_addr = MAX(cw->foreign_addr, len);
+ } else {
+ if (laddr != NULL) {
+ len = formataddr(&laddr->address, NULL, 0);
+ cw->local_addr = MAX(cw->local_addr, len);
}
- /* Remote peer(s) connect(2)ed to us, if any. */
- if (faddr->firstref != 0) {
- struct sock *p;
- struct file *f;
- kvaddr_t ref = faddr->firstref;
- bool fref = true;
-
- pos += xprintf(" <- ");
-
- while ((p = RB_FIND(pcbs_t, &pcbs,
- &(struct sock){ .pcb = ref })) != 0) {
- f = RB_FIND(files_t, &ftree,
- &(struct file){ .xf_data =
- p->socket });
- if (f != NULL) {
- pos += xprintf("%s[%lu %d]",
- fref ? "" : ",",
- (u_long)f->xf_pid,
- f->xf_fd);
- }
- ref = p->faddr->nextref;
- fref = false;
- }
+ if (faddr != NULL) {
+ len = formataddr(&faddr->address, NULL, 0);
+ cw->foreign_addr = MAX(cw->foreign_addr, len);
}
- offset += opt_w ? 92 : 44;
- break;
- default:
- abort();
- }
- while (pos < offset)
- pos += xprintf(" ");
- if (opt_A) {
- pos += xprintf("0x%16lx", s->pcb);
- offset += 18;
}
if (opt_f) {
- pos += xprintf("%d", s->fibnum);
- offset += 7;
+ len = snprintf(NULL, 0, "%d", s->fibnum);
+ cw->fib = MAX(cw->fib, len);
}
if (opt_I) {
if (s->splice_socket != 0) {
struct sock *sp;
sp = RB_FIND(socks_t, &socks, &(struct sock)
- { .socket = s->splice_socket });
+ { .socket = s->splice_socket });
if (sp != NULL) {
- do
- pos += xprintf(" ");
- while (pos < offset);
- pos += printaddr(&sp->laddr->address);
- } else {
- do
- pos += xprintf(" ");
- while (pos < offset);
- pos += xprintf("??");
- offset += opt_w ? 46 : 22;
+ len = formataddr(&sp->laddr->address,
+ NULL, 0);
+ cw->splice_address = MAX(
+ cw->splice_address, len);
}
}
- offset += opt_w ? 46 : 22;
}
if (opt_i) {
- if (s->proto == IPPROTO_TCP ||
- s->proto == IPPROTO_UDP) {
- do
- pos += xprintf(" ");
- while (pos < offset);
- pos += xprintf("%" PRIu64, s->inp_gencnt);
+ if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
+ {
+ len = snprintf(NULL, 0,
+ "%" PRIu64, s->inp_gencnt);
+ cw->inp_gencnt = MAX(cw->inp_gencnt, len);
}
- offset += 9;
}
if (opt_U) {
if (faddr != NULL &&
- ((s->proto == IPPROTO_SCTP &&
- s->state != SCTP_CLOSED &&
- s->state != SCTP_BOUND &&
- s->state != SCTP_LISTEN) ||
- (s->proto == IPPROTO_TCP &&
- s->state != TCPS_CLOSED &&
- s->state != TCPS_LISTEN))) {
- do
- pos += xprintf(" ");
- while (pos < offset);
- pos += xprintf("%u",
- ntohs(faddr->encaps_port));
+ ((s->proto == IPPROTO_SCTP &&
+ s->state != SCTP_CLOSED &&
+ s->state != SCTP_BOUND &&
+ s->state != SCTP_LISTEN) ||
+ (s->proto == IPPROTO_TCP &&
+ s->state != TCPS_CLOSED &&
+ s->state != TCPS_LISTEN))) {
+ len = snprintf(NULL, 0, "%u",
+ ntohs(faddr->encaps_port));
+ cw->encaps = MAX(cw->encaps, len);
}
- offset += 7;
}
if (opt_s) {
if (faddr != NULL &&
- s->proto == IPPROTO_SCTP &&
- s->state != SCTP_CLOSED &&
- s->state != SCTP_BOUND &&
- s->state != SCTP_LISTEN) {
- do
- pos += xprintf(" ");
- while (pos < offset);
- pos += xprintf("%s",
- sctp_path_state(faddr->state));
+ s->proto == IPPROTO_SCTP &&
+ s->state != SCTP_CLOSED &&
+ s->state != SCTP_BOUND &&
+ s->state != SCTP_LISTEN) {
+ len = strlen(sctp_path_state(faddr->state));
+ cw->path_state = MAX(cw->path_state, len);
}
- offset += 13;
+ }
+ if (first) {
+ if (opt_s) {
+ if (s->proto == IPPROTO_SCTP ||
+ s->proto == IPPROTO_TCP) {
+ switch (s->proto) {
+ case IPPROTO_SCTP:
+ len = strlen(
+ sctp_conn_state(s->state));
+ cw->conn_state = MAX(
+ cw->conn_state, len);
+ break;
+ case IPPROTO_TCP:
+ if (s->state >= 0 &&
+ s->state < TCP_NSTATES) {
+ len = strlen(
+ tcpstates[s->state]);
+ cw->conn_state = MAX(
+ cw->conn_state, len);
+ }
+ break;
+ }
+ }
+ }
+ if (opt_S && s->proto == IPPROTO_TCP) {
+ len = strlen(s->stack);
+ cw->stack = MAX(cw->stack, len);
+ }
+ if (opt_C && s->proto == IPPROTO_TCP) {
+ len = strlen(s->cc);
+ cw->cc = MAX(cw->cc, len);
+ }
+ }
+ if (laddr != NULL)
+ laddr = laddr->next;
+ if (faddr != NULL)
+ faddr = faddr->next;
+ first = false;
+ }
+}
+
+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;
+ struct passwd *pwd;
+
+ for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
+ if (xf->xf_data == 0)
+ continue;
+ if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
+ continue;
+ s = RB_FIND(socks_t, &socks,
+ &(struct sock){ .socket = xf->xf_data});
+ if (s == NULL || (!check_ports(s)))
+ continue;
+ s->shown = 1;
+ if (opt_n ||
+ (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
+ len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_uid);
+ else
+ len = snprintf(NULL, 0, "%s", pwd->pw_name);
+ cw->user = MAX(cw->user, len);
+ len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_pid);
+ cw->pid = MAX(cw->pid, len);
+ len = snprintf(NULL, 0, "%d", xf->xf_fd);
+ cw->fd = MAX(cw->fd, len);
+
+ calculate_sock_column_widths(cw, s);
+ }
+ if (opt_j >= 0)
+ return;
+ SLIST_FOREACH(s, &nosocks, socket_list) {
+ if (!check_ports(s))
+ continue;
+ calculate_sock_column_widths(cw, s);
+ }
+ RB_FOREACH(s, socks_t, &socks) {
+ if (s->shown)
+ continue;
+ if (!check_ports(s))
+ continue;
+ calculate_sock_column_widths(cw, s);
+ }
+}
+
+static void
+display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
+{
+ struct addr *laddr, *faddr;
+ bool first;
+ laddr = s->laddr;
+ faddr = s->faddr;
+ first = true;
+
+ snprintf(buf, bufsize, "%s%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)" : "");
+ printf(" %-*s", cw->proto, buf);
+ while (laddr != NULL || faddr != NULL) {
+ if (s->family == AF_UNIX) {
+ if ((laddr == NULL) || (faddr == NULL))
+ errx(1, "laddr = %p or faddr = %p is NULL",
+ (void *)laddr, (void *)faddr);
+ if (laddr->address.ss_len > 0)
+ formataddr(&laddr->address, buf, bufsize);
+ else
+ strlcpy(buf, "??", bufsize);
+ printf(" %-*s", cw->local_addr, buf);
+ if (format_unix_faddr(faddr, buf, bufsize) == 0)
+ strlcpy(buf, "??", bufsize);
+ printf(" %-*s", cw->foreign_addr, buf);
+ } else {
+ if (laddr != NULL)
+ formataddr(&laddr->address, buf, bufsize);
+ else
+ strlcpy(buf, "??", bufsize);
+ printf(" %-*s", cw->local_addr, buf);
+ if (faddr != NULL)
+ formataddr(&faddr->address, buf, bufsize);
+ else
+ strlcpy(buf, "??", bufsize);
+ printf(" %-*s", cw->foreign_addr, buf);
+ }
+ if (opt_A)
+ printf(" %#*" PRIx64, cw->pcb_kva, s->pcb);
+ if (opt_f)
+ printf(" %*d", cw->fib, s->fibnum);
+ if (opt_I) {
+ if (s->splice_socket != 0) {
+ struct sock *sp;
+ sp = RB_FIND(socks_t, &socks, &(struct sock)
+ { .socket = s->splice_socket });
+ if (sp != NULL)
+ formataddr(&sp->laddr->address,
+ buf, bufsize);
+ } else
+ strlcpy(buf, "??", bufsize);
+ printf(" %-*s", cw->splice_address, buf);
+ }
+ if (opt_i) {
+ if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
+ printf(" %*" PRIu64, cw->inp_gencnt,
+ s->inp_gencnt);
+ else
+ printf(" %*s", cw->inp_gencnt, "??");
+ }
+ if (opt_U) {
+ if (faddr != NULL &&
+ ((s->proto == IPPROTO_SCTP &&
+ s->state != SCTP_CLOSED &&
+ s->state != SCTP_BOUND &&
+ s->state != SCTP_LISTEN) ||
+ (s->proto == IPPROTO_TCP &&
+ s->state != TCPS_CLOSED &&
+ s->state != TCPS_LISTEN))) {
+ printf(" %*u", cw->encaps,
+ ntohs(faddr->encaps_port));
+ } else
+ printf(" %*s", cw->encaps, "??");
+ }
+ if (opt_s) {
+ if (faddr != NULL &&
+ s->proto == IPPROTO_SCTP &&
+ s->state != SCTP_CLOSED &&
+ s->state != SCTP_BOUND &&
+ s->state != SCTP_LISTEN) {
+ printf(" %-*s", cw->path_state,
+ sctp_path_state(faddr->state));
+ } else
+ printf(" %-*s", cw->path_state, "??");
}
if (first) {
if (opt_s) {
if (s->proto == IPPROTO_SCTP ||
s->proto == IPPROTO_TCP) {
- do
- pos += xprintf(" ");
- while (pos < offset);
switch (s->proto) {
case IPPROTO_SCTP:
- pos += xprintf("%s",
+ printf(" %-*s", cw->conn_state,
sctp_conn_state(s->state));
break;
case IPPROTO_TCP:
if (s->state >= 0 &&
- s->state < TCP_NSTATES)
- pos += xprintf("%s",
- tcpstates[s->state]);
+ s->state < TCP_NSTATES)
+ printf(" %-*s",
+ cw->conn_state,
+ tcpstates[s->state]);
else
- pos += xprintf("?");
+ printf(" %-*s",
+ cw->conn_state, "??");
break;
}
- }
- offset += 13;
+ } else
+ printf(" %-*s", cw->conn_state, "??");
}
if (opt_S) {
- if (s->proto == IPPROTO_TCP) {
- do
- pos += xprintf(" ");
- while (pos < offset);
- pos += xprintf("%.*s",
- TCP_FUNCTION_NAME_LEN_MAX,
- s->stack);
- }
- offset += TCP_FUNCTION_NAME_LEN_MAX + 1;
+ if (s->proto == IPPROTO_TCP)
+ printf(" %-*s", cw->stack, s->stack);
+ else
+ printf(" %-*s", cw->stack, "??");
}
if (opt_C) {
- if (s->proto == IPPROTO_TCP) {
- do
- pos += xprintf(" ");
- while (pos < offset);
- xprintf("%.*s", TCP_CA_NAME_MAX, s->cc);
- }
- offset += TCP_CA_NAME_MAX + 1;
+ if (s->proto == IPPROTO_TCP)
+ printf(" %-*s", cw->cc, s->cc);
+ else
+ printf(" %-*s", cw->cc, "??");
}
}
if (laddr != NULL)
laddr = laddr->next;
if (faddr != NULL)
faddr = faddr->next;
- if ((laddr != NULL) || (faddr != NULL)) {
- xprintf("\n");
- pos = 0;
- }
- first = 0;
+ if (laddr != NULL || faddr != NULL)
+ printf("%-*s %-*s %-*s %-*s %-*s", cw->user, "",
+ cw->command, "", cw->pid, "", cw->fd, "",
+ cw->proto, "");
+ first = false;
}
- xprintf("\n");
+ printf("\n");
}
static void
@@ -1344,33 +1502,41 @@ display(void)
struct passwd *pwd;
struct file *xf;
struct sock *s;
- int n, pos;
+ int n;
+ struct col_widths cw;
+ const size_t bufsize = 512;
+ void *buf;
+ if ((buf = (char *)malloc(bufsize)) == NULL) {
+ err(1, "malloc()");
+ return;
+ }
+ calculate_column_widths(&cw);
if (!opt_q) {
- printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s",
- "USER", "COMMAND", "PID", "FD", "PROTO",
- opt_w ? 45 : 21, "LOCAL ADDRESS",
- opt_w ? 45 : 21, "FOREIGN ADDRESS");
+ printf("%-*s %-*s %*s %*s %-*s %-*s %-*s",
+ cw.user, "USER", cw.command, "COMMAND",
+ cw.pid, "PID", cw.fd, "FD", cw.proto, "PROTO",
+ cw.local_addr, "LOCAL ADDRESS",
+ cw.foreign_addr,"FOREIGN ADDRESS");
if (opt_A)
- printf(" %-18s", "PCB KVA");
+ printf(" %-*s", cw.pcb_kva, "PCB KVA");
if (opt_f)
/* RT_MAXFIBS is 65535. */
- printf(" %-6s", "FIB");
+ printf(" %*s", cw.fib, "FIB");
if (opt_I)
- printf(" %-*s", opt_w ? 45 : 21, "SPLICE ADDRESS");
+ printf(" %-*s", cw.splice_address, "SPLICE ADDRESS");
if (opt_i)
- printf(" %-8s", "ID");
+ printf(" %*s", cw.inp_gencnt, "ID");
if (opt_U)
- printf(" %-6s", "ENCAPS");
+ printf(" %*s", cw.encaps, "ENCAPS");
if (opt_s) {
- printf(" %-12s", "PATH STATE");
- printf(" %-12s", "CONN STATE");
+ printf(" %-*s", cw.path_state, "PATH STATE");
+ printf(" %-*s", cw.conn_state, "CONN STATE");
}
if (opt_S)
- printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX,
- TCP_FUNCTION_NAME_LEN_MAX, "STACK");
+ printf(" %-*s", cw.stack, "STACK");
if (opt_C)
- printf(" %-.*s", TCP_CA_NAME_MAX, "CC");
+ printf(" %-*s", cw.cc, "CC");
printf("\n");
}
cap_setpassent(cappwd, 1);
@@ -1380,28 +1546,19 @@ display(void)
if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
continue;
s = RB_FIND(socks_t, &socks,
- &(struct sock){ .socket = xf->xf_data});
+ &(struct sock){ .socket = xf->xf_data});
if (s != NULL && check_ports(s)) {
s->shown = 1;
- pos = 0;
if (opt_n ||
(pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
- pos += xprintf("%lu", (u_long)xf->xf_uid);
+ printf("%-*lu", cw.user, (u_long)xf->xf_uid);
else
- pos += xprintf("%s", pwd->pw_name);
- do
- pos += xprintf(" ");
- while (pos < 9);
- pos += xprintf("%.10s", getprocname(xf->xf_pid));
- do
- pos += xprintf(" ");
- while (pos < 20);
- pos += xprintf("%5lu", (u_long)xf->xf_pid);
- do
- pos += xprintf(" ");
- while (pos < 26);
- pos += xprintf("%-3d", xf->xf_fd);
- displaysock(s, pos);
+ printf("%-*s", cw.user, pwd->pw_name);
+ printf(" %-*.*s", cw.command, cw.command,
+ getprocname(xf->xf_pid));
+ printf(" %*lu", cw.pid, (u_long)xf->xf_pid);
+ printf(" %*d", cw.fd, xf->xf_fd);
+ display_sock(s, &cw, buf, bufsize);
}
}
if (opt_j >= 0)
@@ -1409,19 +1566,20 @@ display(void)
SLIST_FOREACH(s, &nosocks, socket_list) {
if (!check_ports(s))
continue;
- pos = xprintf("%-8s %-10s %-5s %-3s",
- "?", "?", "?", "?");
- displaysock(s, pos);
+ printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??",
+ cw.pid, "??", cw.fd, "??");
+ display_sock(s, &cw, buf, bufsize);
}
RB_FOREACH(s, socks_t, &socks) {
if (s->shown)
continue;
if (!check_ports(s))
continue;
- pos = xprintf("%-8s %-10s %-5s %-3s",
- "?", "?", "?", "?");
- displaysock(s, pos);
+ printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??",
+ cw.pid, "??", cw.fd, "??");
+ display_sock(s, &cw, buf, bufsize);
}
+ free(buf);
}
static int
@@ -1484,7 +1642,7 @@ static void
usage(void)
{
errx(1,
- "usage: sockstat [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]");
+ "usage: sockstat [-46ACcfIiLlnqSsUuv] [-j jid] [-p ports] [-P protocols]");
}
int
@@ -1563,7 +1721,7 @@ main(int argc, char *argv[])
++opt_v;
break;
case 'w':
- opt_w = true;
+ /* left for backward compatibility. */
break;
default:
usage();