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
This commit is contained in:
Damin Rido 2025-06-12 14:42:49 +05:30 committed by Alan Somers
parent 2c6e4aed07
commit 0726c6574f
2 changed files with 397 additions and 241 deletions

View file

@ -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

View file

@ -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 void
displaysock(struct sock *s, int pos)
{
int first, offset;
struct addr *laddr, *faddr;
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)
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(" ");
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
calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
{
struct addr *laddr, *faddr;
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) {
do
pos += xprintf(" ");
while (pos < offset);
s->proto == IPPROTO_TCP) {
switch (s->proto) {
case IPPROTO_SCTP:
pos += xprintf("%s",
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)
pos += xprintf("%s",
tcpstates[s->state]);
else
pos += xprintf("?");
s->state < TCP_NSTATES) {
len = strlen(
tcpstates[s->state]);
cw->conn_state = MAX(
cw->conn_state, len);
}
break;
}
}
offset += 13;
}
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 (opt_S && s->proto == IPPROTO_TCP) {
len = strlen(s->stack);
cw->stack = MAX(cw->stack, len);
}
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 (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;
if ((laddr != NULL) || (faddr != NULL)) {
xprintf("\n");
pos = 0;
}
first = 0;
first = false;
}
xprintf("\n");
}
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) {
switch (s->proto) {
case IPPROTO_SCTP:
printf(" %-*s", cw->conn_state,
sctp_conn_state(s->state));
break;
case IPPROTO_TCP:
if (s->state >= 0 &&
s->state < TCP_NSTATES)
printf(" %-*s",
cw->conn_state,
tcpstates[s->state]);
else
printf(" %-*s",
cw->conn_state, "??");
break;
}
} else
printf(" %-*s", cw->conn_state, "??");
}
if (opt_S) {
if (s->proto == IPPROTO_TCP)
printf(" %-*s", cw->stack, s->stack);
else
printf(" %-*s", cw->stack, "??");
}
if (opt_C) {
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)
printf("%-*s %-*s %-*s %-*s %-*s", cw->user, "",
cw->command, "", cw->pid, "", cw->fd, "",
cw->proto, "");
first = false;
}
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();