Page MenuHomeFreeBSD

D50698.id156574.diff
No OneTemporary

D50698.id156574.diff

diff --git a/usr.bin/fstat/fstat.1 b/usr.bin/fstat/fstat.1
--- a/usr.bin/fstat/fstat.1
+++ b/usr.bin/fstat/fstat.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd November 19, 2020
+.Dd June 3, 2025
.Dt FSTAT 1
.Os
.Sh NAME
@@ -33,6 +33,7 @@
.Nd identify active files
.Sh SYNOPSIS
.Nm
+.Op Fl -libxo
.Op Fl fmnsv
.Op Fl M Ar core
.Op Fl N Ar system
@@ -52,6 +53,13 @@
.Pp
The following options are available:
.Bl -tag -width "-N system"
+.It Fl -libxo
+Generate output via
+.Xr libxo 3
+in a selection of different human and machine readable formats.
+See
+.Xr xo_parse_args 3
+for details on command line arguments.
.It Fl f
Restrict examination to files open in the same file systems as
the named file arguments, or to the file system containing the
@@ -327,6 +335,8 @@
.Xr ps 1 ,
.Xr sockstat 1 ,
.Xr systat 1 ,
+.Xr libxo 3 ,
+.Xr xo_parse_args 3 ,
.Xr tcp 4 ,
.Xr unix 4 ,
.Xr iostat 8 ,
diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c
--- a/usr.bin/fstat/fstat.c
+++ b/usr.bin/fstat/fstat.c
@@ -45,8 +45,9 @@
#include <assert.h>
#include <ctype.h>
-#include <err.h>
+#include <errno.h>
#include <libprocstat.h>
+#include <libxo/xo.h>
#include <limits.h>
#include <pwd.h>
#include <stdint.h>
@@ -104,11 +105,15 @@
struct passwd *passwd;
struct procstat *procstat;
int arg, ch, what;
- int cnt, i;
-
+ unsigned int cnt, i;
arg = 0;
what = KERN_PROC_PROC;
nlistf = memf = NULL;
+ /* parse --libxo arguments first */
+ argc = xo_parse_args(argc, argv);
+ if (argc < 0)
+ xo_errx(1, "libxo argument parsing failed");
+
while ((ch = getopt(argc, argv, "fmnp:su:vN:M:")) != -1)
switch((char)ch) {
case 'f':
@@ -130,7 +135,7 @@
if (pflg++)
usage();
if (!isdigit(*optarg)) {
- warnx("-p requires a process id");
+ xo_warnx("-p requires a process id");
usage();
}
what = KERN_PROC_PID;
@@ -143,7 +148,7 @@
if (uflg++)
usage();
if (!(passwd = getpwnam(optarg)))
- errx(1, "%s: unknown uid", optarg);
+ xo_errx(1, "%s: unknown uid", optarg);
what = KERN_PROC_UID;
arg = passwd->pw_uid;
break;
@@ -176,24 +181,30 @@
else
procstat = procstat_open_sysctl();
if (procstat == NULL)
- errx(1, "procstat_open()");
+ xo_errx(1, "procstat_open_sysctl() failed: %s", strerror(errno));
p = procstat_getprocs(procstat, what, arg, &cnt);
if (p == NULL)
- errx(1, "procstat_getprocs()");
+ xo_errx(1, "procstat_getprocs() failed: %s", strerror(errno));
- /*
- * Print header.
- */
- if (nflg)
- printf("%s",
-"USER CMD PID FD DEV INUM MODE SZ|DV R/W");
- else
- printf("%s",
-"USER CMD PID FD MOUNT INUM MODE SZ|DV R/W");
- if (checkfile && fsflg == 0)
- printf(" NAME\n");
- else
- putchar('\n');
+/*
+ * Print header.
+ */
+xo_open_container("fstat-information");
+if (nflg) {
+ xo_emit("{T:/%-9s}{T:/%-13s}{T:/%-6s}{T:/%-4s}{T:/%-7s}{T:/%-11s}",
+ "{T:/%-5s}{T:/%-6s}{T:/%-s}",
+ "USER", "CMD", "PID", "FD", "DEV",
+ "INUM", "MODE", "SZ|DV ", "R/W");
+} else {
+ xo_emit("{T:/%-9s}{T:/%-13s}{T:/%-6s}{T:/%-3s}{T:/%-11s}{T:/%-5s}",
+ "{T:/%-13s}{T:/%-6s}{T:/%-3s}",
+ "USER", "CMD", "PID", "FD", "MOUNT",
+ "INUM", "MODE", "SZ|DV", "R/W");
+}
+if (checkfile && fsflg == 0)
+ xo_emit("{T:/ NAME}\n");
+else
+ xo_emit("\n");
/*
* Go through the process list.
@@ -203,8 +214,10 @@
continue;
dofiles(procstat, &p[i]);
}
+ xo_close_container("fstat-information");
procstat_freeprocs(procstat, p);
procstat_close(procstat);
+ xo_finish();
return (0);
}
@@ -224,8 +237,10 @@
head = procstat_getfiles(procstat, kp, mflg);
if (head == NULL)
return;
+ xo_open_list("files");
STAILQ_FOREACH(fst, head, next)
print_file_info(procstat, fst, uname, cmd, pid);
+ xo_close_list("files");
procstat_freefiles(procstat, head);
}
@@ -261,61 +276,76 @@
return;
}
- /*
- * Print entry prefix.
- */
- printf("%-8.8s %-10s %5d", uname, cmd, pid);
- if (fst->fs_uflags & PS_FST_UFLAG_TEXT)
- printf(" text");
- else if (fst->fs_uflags & PS_FST_UFLAG_CDIR)
- printf(" wd");
- else if (fst->fs_uflags & PS_FST_UFLAG_RDIR)
- printf(" root");
- else if (fst->fs_uflags & PS_FST_UFLAG_TRACE)
- printf(" tr");
- else if (fst->fs_uflags & PS_FST_UFLAG_MMAP)
- printf(" mmap");
- else if (fst->fs_uflags & PS_FST_UFLAG_JAIL)
- printf(" jail");
- else if (fst->fs_uflags & PS_FST_UFLAG_CTTY)
- printf(" ctty");
- else
- printf(" %4d", fst->fs_fd);
+ /*
+ * Print entry prefix.
+ */
+ xo_open_instance("file");
+
+ xo_emit("{:user/%-8.8s/%s} {:command/%-10s/%s} {:pid/%5d/%d}", uname, cmd,
+ pid);
+
+ if (fst->fs_uflags & PS_FST_UFLAG_TEXT) {
+ xo_emit(" {:fd/text}");
+ } else if (fst->fs_uflags & PS_FST_UFLAG_CDIR) {
+ xo_emit(" {:fd/wd}");
+ } else if (fst->fs_uflags & PS_FST_UFLAG_RDIR) {
+ xo_emit(" {:fd/root}");
+ } else if (fst->fs_uflags & PS_FST_UFLAG_TRACE) {
+ xo_emit(" {:fd/tr}");
+ } else if (fst->fs_uflags & PS_FST_UFLAG_MMAP) {
+ xo_emit(" {:fd/mmap}");
+ } else if (fst->fs_uflags & PS_FST_UFLAG_JAIL) {
+ xo_emit(" {:fd/jail}");
+ } else if (fst->fs_uflags & PS_FST_UFLAG_CTTY) {
+ xo_emit(" {:fd/ctty}");
+ } else {
+ xo_emit(" {:fd/%4d}", fst->fs_fd);
+ }
/*
* Print type-specific data.
*/
- switch (fst->fs_type) {
+switch (fst->fs_type) {
case PS_FST_TYPE_FIFO:
+ xo_emit("{e:file_type/fifo}");
+ print_vnode_info(procstat, fst);
+ break;
case PS_FST_TYPE_VNODE:
+ xo_emit("{e:file_type/vnode}");
print_vnode_info(procstat, fst);
break;
case PS_FST_TYPE_SOCKET:
+ xo_emit("{e:file_type/socket}");
print_socket_info(procstat, fst);
break;
case PS_FST_TYPE_PIPE:
+ xo_emit("{e:file_type/pipe}");
print_pipe_info(procstat, fst);
break;
case PS_FST_TYPE_PTS:
+ xo_emit("{e:file_type/pts}");
print_pts_info(procstat, fst);
break;
case PS_FST_TYPE_SHM:
+ xo_emit("{e:file_type/shm}");
print_shm_info(procstat, fst);
break;
case PS_FST_TYPE_SEM:
+ xo_emit("{e:file_type/sem}");
print_sem_info(procstat, fst);
break;
case PS_FST_TYPE_DEV:
break;
default:
+ xo_emit("{e:file_type/unknown}");
if (vflg)
- fprintf(stderr,
- "unknown file type %d for file %d of pid %d\n",
+ xo_warnx("unknown file type %d for file %d of pid %d",
fst->fs_type, fst->fs_fd, pid);
}
if (filename && !fsflg)
- printf(" %s", filename);
- putchar('\n');
+ xo_emit(" {:filename/ %s}", filename);
+ xo_emit("\n");
+ xo_close_instance("file");
}
static char *
@@ -387,15 +417,19 @@
int error;
static int isopen;
+ xo_open_container("socket");
error = procstat_get_socket_info(procstat, fst, &sock, errbuf);
- if (error != 0) {
- printf("* error");
- return;
- }
- if (sock.type > STYPEMAX)
- printf("* %s ?%d", sock.dname, sock.type);
+ if (error != 0) {
+ xo_emit(" {:socket_error/error}");
+ xo_close_container("socket");
+ return;
+ }
+ if (sock.type > STYPEMAX)
+ xo_emit("* {:socket_domain/%s} {:socket_type_unknown/?%d}", sock.dname,
+ sock.type);
else
- printf("* %s %s", sock.dname, stypename[sock.type]);
+ xo_emit("* {:socket_domain/%s} {:socket_type/%s}", sock.dname,
+ stypename[sock.type]);
/*
* protocol specific formatting
@@ -413,21 +447,21 @@
if (!isopen)
setprotoent(++isopen);
if ((pe = getprotobynumber(sock.proto)) != NULL)
- printf(" %s", pe->p_name);
+ xo_emit(" {:protocol_name/%s}", pe->p_name);
else
- printf(" %d", sock.proto);
+ xo_emit(" {:protocol_number/%d}", sock.proto);
if (sock.so_pcb != 0)
- printf(" %lx", (u_long)sock.so_pcb);
+ xo_emit(" {:pcb_address/%lx}", (u_long)sock.so_pcb);
if (!sflg)
break;
- printf(" %s <-> %s",
- addr_to_string(&sock.sa_local, src_addr, sizeof(src_addr)),
- addr_to_string(&sock.sa_peer, dst_addr, sizeof(dst_addr)));
+ xo_emit(" {:local-address/%s} <-> {:remote-address/%s}",
+ addr_to_string(&sock.sa_local, src_addr, sizeof(src_addr)),
+ addr_to_string(&sock.sa_peer, dst_addr, sizeof(dst_addr)));
break;
case AF_UNIX:
/* print address of pcb and connected pcb */
if (sock.so_pcb != 0) {
- printf(" %lx", (u_long)sock.so_pcb);
+ xo_emit(" {:pcb_address/%lx}", (u_long)sock.so_pcb);
if (sock.unp_conn) {
char shoconn[4], *cp;
@@ -438,8 +472,8 @@
if (!(sock.so_snd_sb_state & SBS_CANTSENDMORE))
*cp++ = '>';
*cp = '\0';
- printf(" %s %lx", shoconn,
- (u_long)sock.unp_conn);
+ xo_emit(" {:connection_status/%s} {:connected_pcb_address/%lx}",
+ shoconn, (u_long)sock.unp_conn);
}
}
if (!sflg)
@@ -458,12 +492,14 @@
else
addr_to_string(&sock.sa_peer,
src_addr, sizeof(src_addr));
- printf(" %s", src_addr);
+ xo_emit(" {:unix_socket_path/ %s}", src_addr);
break;
default:
/* print protocol number and socket address */
- printf(" %d %lx", sock.proto, (u_long)sock.so_addr);
+ xo_emit(" {:protocol_number/%d} {:socket_address/%lx}", sock.proto,
+ (u_long)sock.so_addr);
}
+ xo_close_container("socket");
}
static void
@@ -475,12 +511,15 @@
error = procstat_get_pipe_info(procstat, fst, &ps, errbuf);
if (error != 0) {
- printf("* error");
+ xo_emit("* {:type/error}");
return;
}
- printf("* pipe %8lx <-> %8lx", (u_long)ps.addr, (u_long)ps.peer);
- printf(" %6zd", ps.buffer_cnt);
+ xo_open_container("pipe");
+ xo_emit("* {:type/pipe} {:pipe-addr/%8lx/%lx} <-> {:peer-addr/%8lx/%lx}",
+ (u_long)ps.addr, (u_long)ps.peer);
+ xo_emit(" {:buffer-count/%6zd/%zd}", ps.buffer_cnt);
print_access_flags(fst->fs_fflags);
+ xo_close_container("pipe");
}
static void
@@ -492,16 +531,18 @@
error = procstat_get_pts_info(procstat, fst, &pts, errbuf);
if (error != 0) {
- printf("* error");
+ xo_emit("* {:type/error}");
return;
}
- printf("* pseudo-terminal master ");
+ xo_open_container("pts");
+ xo_emit("* {:type/pseudo-terminal master} ");
if (nflg || !*pts.devname) {
- printf("%#10jx", (uintmax_t)pts.dev);
+ xo_emit("{:device/%#10jx/%#jx}", (uintmax_t)pts.dev);
} else {
- printf("%10s", pts.devname);
+ xo_emit("{:device/%10s/%s}", pts.devname);
}
print_access_flags(fst->fs_fflags);
+ xo_close_container("pts");
}
static void
@@ -514,18 +555,20 @@
error = procstat_get_sem_info(procstat, fst, &sem, errbuf);
if (error != 0) {
- printf("* error");
+ xo_emit("* {:type/error}");
return;
}
+ xo_open_container("sem");
if (nflg) {
- printf(" ");
+ xo_emit("{:mount/%13s/%s}", "");
(void)snprintf(mode, sizeof(mode), "%o", sem.mode);
} else {
- printf(" %-15s", fst->fs_path != NULL ? fst->fs_path : "-");
+ xo_emit(" {:mount/%-15s/%s}", fst->fs_path != NULL ? fst->fs_path : "-");
strmode(sem.mode, mode);
}
- printf(" %10s %6u", mode, sem.value);
+ xo_emit(" {:mode/%10s/%s} {:value/%6u/%u}", mode, sem.value);
print_access_flags(fst->fs_fflags);
+ xo_close_container("sem");
}
static void
@@ -538,18 +581,20 @@
error = procstat_get_shm_info(procstat, fst, &shm, errbuf);
if (error != 0) {
- printf("* error");
+ xo_emit("* {:type/error}");
return;
}
+ xo_open_container("shm");
if (nflg) {
- printf(" ");
+ xo_emit("{:mount/%13s/%s}", "");
(void)snprintf(mode, sizeof(mode), "%o", shm.mode);
} else {
- printf(" %-15s", fst->fs_path != NULL ? fst->fs_path : "-");
+ xo_emit(" {:mount/%-15s/%s}", fst->fs_path != NULL ? fst->fs_path : "-");
strmode(shm.mode, mode);
}
- printf(" %10s %6ju", mode, shm.size);
+ xo_emit(" {:mode/%10s/%s} {:size/%6ju/%ju}", mode, shm.size);
print_access_flags(fst->fs_fflags);
+ xo_close_container("shm");
}
static void
@@ -569,15 +614,18 @@
badtype = "bad";
else if (vn.vn_type == PS_FST_VTYPE_VNON)
badtype = "none";
+ xo_open_container("vnode");
if (badtype != NULL) {
- printf(" - - %10s -", badtype);
+ xo_emit(" {:mount/%-9s/%s} {:inode/%10s/%s} {:size/%-6s/%s}",
+ "-", badtype, "-");
+ xo_close_container("vnode");
return;
}
-
+
if (nflg)
- printf(" %#5jx", (uintmax_t)vn.vn_fsid);
+ xo_emit(" {:mount/%#5jx/%#jx}", (uintmax_t)vn.vn_fsid);
else if (vn.vn_mntdir != NULL)
- (void)printf(" %-8s", vn.vn_mntdir);
+ xo_emit(" {:mount/%-8s/%s}", vn.vn_mntdir);
/*
* Print access mode.
@@ -587,30 +635,34 @@
else {
strmode(vn.vn_mode, mode);
}
- (void)printf(" %6jd %10s", (intmax_t)vn.vn_fileid, mode);
-
+ xo_emit(" {:inode/%6jd/%jd} {:mode/%10s/%s}", (intmax_t)vn.vn_fileid, mode);
+
if (vn.vn_type == PS_FST_VTYPE_VBLK || vn.vn_type == PS_FST_VTYPE_VCHR) {
if (nflg || !*vn.vn_devname)
- printf(" %#6jx", (uintmax_t)vn.vn_dev);
+ xo_emit(" {:size/%#6jx/%#jx}", (uintmax_t)vn.vn_dev);
else {
- printf(" %6s", vn.vn_devname);
+ xo_emit(" {:size/%6s/%s}", vn.vn_devname);
}
} else
- printf(" %6ju", (uintmax_t)vn.vn_size);
+ xo_emit(" {:size/%6ju/%ju}", (uintmax_t)vn.vn_size);
+
print_access_flags(fst->fs_fflags);
+ xo_close_container("vnode");
}
+
static void
print_access_flags(int flags)
{
char rw[3];
-
+ xo_open_container("access");
rw[0] = '\0';
if (flags & PS_FST_FFLAG_READ)
strcat(rw, "r");
if (flags & PS_FST_FFLAG_WRITE)
strcat(rw, "w");
- printf(" %2s", rw);
+ xo_emit(" {:access_flags/%2s}", rw);
+ xo_close_container("access");
}
int
@@ -618,16 +670,16 @@
{
struct stat statbuf;
DEVS *cur;
-
+
if (stat(filename, &statbuf)) {
- warn("%s", filename);
+ xo_warn("%s", filename);
return (0);
}
if ((cur = malloc(sizeof(DEVS))) == NULL)
- err(1, NULL);
+ xo_err(1, NULL);
+
cur->next = devs;
devs = cur;
-
cur->ino = statbuf.st_ino;
cur->fsid = statbuf.st_dev;
cur->name = filename;
@@ -637,7 +689,8 @@
static void
usage(void)
{
- (void)fprintf(stderr,
- "usage: fstat [-fmnv] [-M core] [-N system] [-p pid] [-u user] [file ...]\n");
+ xo_error(
+ "usage: fstat [-fmnv] [-M core] [-N system] [-p pid] [-u user] "
+ "[file ...]\n");
exit(1);
}

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 12:24 PM (5 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28578317
Default Alt Text
D50698.id156574.diff (13 KB)

Event Timeline