Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144450074
D50698.id156574.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D50698.id156574.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D50698: patch libxo support for fstat
Attached
Detach File
Event Timeline
Log In to Comment