socsvn commit: r269005 - soc2014/zkorchev/freebsd_head/usr.bin/fstat
zkorchev at FreeBSD.org
zkorchev at FreeBSD.org
Tue Jun 3 13:22:03 UTC 2014
Author: zkorchev
Date: Tue Jun 3 13:22:02 2014
New Revision: 269005
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269005
Log:
fstat JSON output
Modified:
soc2014/zkorchev/freebsd_head/usr.bin/fstat/Makefile
soc2014/zkorchev/freebsd_head/usr.bin/fstat/fstat.1
soc2014/zkorchev/freebsd_head/usr.bin/fstat/fstat.c
Modified: soc2014/zkorchev/freebsd_head/usr.bin/fstat/Makefile
==============================================================================
--- soc2014/zkorchev/freebsd_head/usr.bin/fstat/Makefile Tue Jun 3 10:56:55 2014 (r269004)
+++ soc2014/zkorchev/freebsd_head/usr.bin/fstat/Makefile Tue Jun 3 13:22:02 2014 (r269005)
@@ -5,7 +5,8 @@
SRCS= fstat.c fuser.c main.c
LINKS= ${BINDIR}/fstat ${BINDIR}/fuser
DPADD= ${LIBKVM} ${LIBUTIL} ${LIBPROCSTAT}
-LDADD= -lkvm -lutil -lprocstat
+LDADD= -lkvm -lutil -lprocstat -lsol
+CFLAGS+= -DSOL_ON -I/usr/local/include
MAN1= fuser.1 fstat.1
Modified: soc2014/zkorchev/freebsd_head/usr.bin/fstat/fstat.1
==============================================================================
--- soc2014/zkorchev/freebsd_head/usr.bin/fstat/fstat.1 Tue Jun 3 10:56:55 2014 (r269004)
+++ soc2014/zkorchev/freebsd_head/usr.bin/fstat/fstat.1 Tue Jun 3 13:22:02 2014 (r269005)
@@ -71,6 +71,8 @@
.It Fl N
Extract the name list from the specified system instead of the default,
which is the kernel image the system has booted from.
+.It Fl O
+Output the results in JSON format.
.It Fl m
Include memory-mapped files in the listing; normally these are excluded
due to the extra processing required.
Modified: soc2014/zkorchev/freebsd_head/usr.bin/fstat/fstat.c
==============================================================================
--- soc2014/zkorchev/freebsd_head/usr.bin/fstat/fstat.c Tue Jun 3 10:56:55 2014 (r269004)
+++ soc2014/zkorchev/freebsd_head/usr.bin/fstat/fstat.c Tue Jun 3 13:22:02 2014 (r269005)
@@ -54,6 +54,7 @@
#include <string.h>
#include <unistd.h>
#include <netdb.h>
+#include <sol.h>
#include "functions.h"
@@ -64,6 +65,7 @@
static int nflg; /* (numerical) display f.s. and rdev as dev_t */
static int mflg; /* include memory-mapped files */
static int vflg; /* be verbose */
+static int Oflg; /* use JSON as output format */
typedef struct devs {
struct devs *next;
@@ -75,6 +77,8 @@
static DEVS *devs;
static char *memf, *nlistf;
+static struct sol_stream sol_stream;
+
static int getfname(const char *filename);
static void dofiles(struct procstat *procstat, struct kinfo_proc *p);
static void print_access_flags(int flags);
@@ -103,10 +107,14 @@
int arg, ch, what;
int cnt, i;
+ /* prevent unused variable warnings */
+ (void)sol_stream;
+ (void)Oflg;
+
arg = 0;
what = KERN_PROC_PROC;
nlistf = memf = NULL;
- while ((ch = getopt(argc, argv, "fmnp:u:vN:M:")) != -1)
+ while ((ch = getopt(argc, argv, "fmnp:u:vN:M:O")) != -1)
switch((char)ch) {
case 'f':
fsflg = 1;
@@ -144,6 +152,13 @@
case 'v':
vflg = 1;
break;
+ case 'O':
+#if defined(SOL_ON)
+ Oflg = 1;
+#else
+ errx(1, "compiled without -O support");
+#endif
+ break;
case '?':
default:
usage();
@@ -175,19 +190,29 @@
if (p == NULL)
errx(1, "procstat_getprocs()");
- /*
- * 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");
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ sol_init(&sol_stream, SOL_JSON);
+ sol_array_start(&sol_stream);
+ }
else
- putchar('\n');
+#endif
+ {
+ /*
+ * 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');
+ }
/*
* Go through the process list.
@@ -197,6 +222,14 @@
continue;
dofiles(procstat, &p[i]);
}
+
+#if defined(SOL_ON)
+ if (Oflg) {
+ sol_array_end(&sol_stream);
+ sol_term(&sol_stream);
+ }
+#endif
+
procstat_freeprocs(procstat, p);
procstat_close(procstat);
return (0);
@@ -218,8 +251,17 @@
head = procstat_getfiles(procstat, kp, mflg);
if (head == NULL)
return;
- STAILQ_FOREACH(fst, head, next)
- print_file_info(procstat, fst, uname, cmd, pid);
+ STAILQ_FOREACH(fst, head, next) {
+#if defined(SOL_ON)
+ if (Oflg) {
+ sol_map_start(&sol_stream);
+ print_file_info(procstat, fst, uname, cmd, pid);
+ sol_map_end(&sol_stream);
+ }
+ else
+#endif
+ print_file_info(procstat, fst, uname, cmd, pid);
+ }
procstat_freefiles(procstat, head);
}
@@ -255,26 +297,60 @@
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");
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ sol_map_key(&sol_stream, "user", 4);
+ sol_string(&sol_stream, uname, strlen(uname));
+
+ sol_map_key(&sol_stream, "cmd", 3);
+ sol_string(&sol_stream, cmd, strlen(cmd));
+
+ sol_map_key(&sol_stream, "pid", 3);
+ sol_integer(&sol_stream, pid);
+
+ sol_map_key(&sol_stream, "fd", 2);
+ if (fst->fs_uflags & PS_FST_UFLAG_TEXT)
+ sol_string(&sol_stream, "text", 4);
+ else if (fst->fs_uflags & PS_FST_UFLAG_CDIR)
+ sol_string(&sol_stream, "wd", 2);
+ else if (fst->fs_uflags & PS_FST_UFLAG_RDIR)
+ sol_string(&sol_stream, "root", 4);
+ else if (fst->fs_uflags & PS_FST_UFLAG_TRACE)
+ sol_string(&sol_stream, "tr", 2);
+ else if (fst->fs_uflags & PS_FST_UFLAG_MMAP)
+ sol_string(&sol_stream, "mmap", 4);
+ else if (fst->fs_uflags & PS_FST_UFLAG_JAIL)
+ sol_string(&sol_stream, "jail", 4);
+ else if (fst->fs_uflags & PS_FST_UFLAG_CTTY)
+ sol_string(&sol_stream, "ctty", 4);
+ else
+ sol_integer(&sol_stream, fst->fs_fd);
+ }
else
- printf(" %4d", fst->fs_fd);
+#endif
+ {
+ /*
+ * 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 type-specific data.
@@ -305,9 +381,17 @@
"unknown file type %d for file %d of pid %d\n",
fst->fs_type, fst->fs_fd, pid);
}
- if (filename && !fsflg)
- printf(" %s", filename);
- putchar('\n');
+ if (filename && !fsflg) {
+#if defined(SOL_ON)
+ if (Oflg) {
+ sol_map_key(&sol_stream, "name", 4);
+ sol_string(&sol_stream, filename, strlen(filename));
+ }
+ else
+#endif
+ printf(" %s", filename);
+ }
+ if (!Oflg) putchar('\n');
}
static void
@@ -330,13 +414,29 @@
error = procstat_get_socket_info(procstat, fst, &sock, errbuf);
if (error != 0) {
- printf("* error");
+ if (!Oflg) printf("* error");
return;
}
- if (sock.type > STYPEMAX)
- printf("* %s ?%d", sock.dname, sock.type);
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ sol_map_key(&sol_stream, "socket", 6);
+ sol_string(&sol_stream, sock.dname, strlen(sock.dname));
+
+ sol_map_key(&sol_stream, "type", 4);
+ if (sock.type > STYPEMAX)
+ sol_integer(&sol_stream, sock.type);
+ else
+ sol_string(&sol_stream, stypename[sock.type], strlen(stypename[sock.type]));
+ }
else
- printf("* %s %s", sock.dname, stypename[sock.type]);
+#endif
+ {
+ if (sock.type > STYPEMAX)
+ printf("* %s ?%d", sock.dname, sock.type);
+ else
+ printf("* %s %s", sock.dname, stypename[sock.type]);
+ }
/*
* protocol specific formatting
@@ -354,21 +454,52 @@
case AF_INET6:
if (!isopen)
setprotoent(++isopen);
- if ((pe = getprotobynumber(sock.proto)) != NULL)
- printf(" %s", pe->p_name);
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ sol_map_key(&sol_stream, "proto", 5);
+ if ((pe = getprotobynumber(sock.proto)) != NULL)
+ sol_string(&sol_stream, pe->p_name, strlen(pe->p_name));
+ else
+ sol_integer(&sol_stream, sock.proto);
+ if (sock.proto == IPPROTO_TCP ) {
+ if (sock.inp_ppcb != 0) {
+ sol_map_key(&sol_stream, "ppcb", 4);
+ sol_integer(&sol_stream, sock.inp_ppcb); // TODO hex?
+ }
+ }
+ else if (sock.so_pcb != 0) {
+ sol_map_key(&sol_stream, "pcb", 3);
+ sol_integer(&sol_stream, sock.so_pcb); // TODO hex?
+ }
+ }
else
- printf(" %d", sock.proto);
- if (sock.proto == IPPROTO_TCP ) {
- if (sock.inp_ppcb != 0)
- printf(" %lx", (u_long)sock.inp_ppcb);
+#endif
+ {
+ if ((pe = getprotobynumber(sock.proto)) != NULL)
+ printf(" %s", pe->p_name);
+ else
+ printf(" %d", sock.proto);
+ if (sock.proto == IPPROTO_TCP ) {
+ if (sock.inp_ppcb != 0)
+ printf(" %lx", (u_long)sock.inp_ppcb);
+ }
+ else if (sock.so_pcb != 0)
+ printf(" %lx", (u_long)sock.so_pcb);
}
- else if (sock.so_pcb != 0)
- printf(" %lx", (u_long)sock.so_pcb);
break;
case AF_UNIX:
/* print address of pcb and connected pcb */
if (sock.so_pcb != 0) {
- printf(" %lx", (u_long)sock.so_pcb);
+#if defined(SOL_ON)
+ if (Oflg) {
+ sol_map_key(&sol_stream, "pcb", 3);
+ sol_integer(&sol_stream, sock.so_pcb); // TODO hex?
+ }
+ else
+#endif
+ printf(" %lx", (u_long)sock.so_pcb);
+
if (sock.unp_conn) {
char shoconn[4], *cp;
@@ -379,14 +510,31 @@
if (!(sock.so_snd_sb_state & SBS_CANTSENDMORE))
*cp++ = '>';
*cp = '\0';
- printf(" %s %lx", shoconn,
- (u_long)sock.unp_conn);
- }
+#if defined(SOL_ON)
+ if (Oflg) {
+ sol_map_key(&sol_stream, "flow", 4);
+ sol_string(&sol_stream, shoconn, cp - shoconn);
+ sol_map_key(&sol_stream, "conn", 4);
+ sol_integer(&sol_stream, sock.unp_conn); // TODO hex?
+ }
+ else
+#endif
+ printf(" %s %lx", shoconn, (u_long)sock.unp_conn);
+ }
}
break;
default:
/* print protocol number and socket address */
- printf(" %d %lx", sock.proto, (u_long)sock.so_addr);
+#if defined(SOL_ON)
+ if (Oflg) {
+ sol_map_key(&sol_stream, "proto", 5);
+ sol_integer(&sol_stream, sock.proto);
+ sol_map_key(&sol_stream, "address", 7);
+ sol_integer(&sol_stream, sock.so_addr);
+ }
+ else
+#endif
+ printf(" %d %lx", sock.proto, (u_long)sock.so_addr);
}
}
@@ -399,11 +547,24 @@
error = procstat_get_pipe_info(procstat, fst, &ps, errbuf);
if (error != 0) {
- printf("* error");
+ if (!Oflg) printf("* error");
return;
}
- printf("* pipe %8lx <-> %8lx", (u_long)ps.addr, (u_long)ps.peer);
- printf(" %6zd", ps.buffer_cnt);
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ sol_map_key(&sol_stream, "pipe", 4);
+ sol_array_start(&sol_stream);
+ sol_integer(&sol_stream, (u_long)ps.addr);
+ sol_integer(&sol_stream, (u_long)ps.peer);
+ sol_array_end(&sol_stream);
+ }
+ else
+#endif
+ {
+ printf("* pipe %8lx <-> %8lx", (u_long)ps.addr, (u_long)ps.peer);
+ printf(" %6zd", ps.buffer_cnt);
+ }
print_access_flags(fst->fs_fflags);
}
@@ -416,14 +577,29 @@
error = procstat_get_pts_info(procstat, fst, &pts, errbuf);
if (error != 0) {
- printf("* error");
+ if (!Oflg) printf("* error");
return;
}
- printf("* pseudo-terminal master ");
- if (nflg || !*pts.devname) {
- printf("%#10jx", (uintmax_t)pts.dev);
- } else {
- printf("%10s", pts.devname);
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ if (nflg || !*pts.devname) {
+ sol_map_key(&sol_stream, "ptm", 3);
+ sol_integer(&sol_stream, pts.dev);
+ } else {
+ sol_map_key(&sol_stream, "ptmname", 7);
+ sol_string(&sol_stream, pts.devname, strlen(pts.devname));
+ }
+ }
+ else
+#endif
+ {
+ printf("* pseudo-terminal master ");
+ if (nflg || !*pts.devname) {
+ printf("%#10jx", (uintmax_t)pts.dev);
+ } else {
+ printf("%10s", pts.devname);
+ }
}
print_access_flags(fst->fs_fflags);
}
@@ -438,17 +614,39 @@
error = procstat_get_sem_info(procstat, fst, &sem, errbuf);
if (error != 0) {
- printf("* error");
+ if (!Oflg) printf("* error");
return;
}
- if (nflg) {
- printf(" ");
- (void)snprintf(mode, sizeof(mode), "%o", sem.mode);
- } else {
- printf(" %-15s", fst->fs_path != NULL ? fst->fs_path : "-");
- strmode(sem.mode, mode);
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ if (nflg) {
+ (void)snprintf(mode, sizeof(mode), "%o", sem.mode);
+ }
+ else {
+ if (fst->fs_path) {
+ sol_map_key(&sol_stream, "path", 4);
+ sol_string(&sol_stream, fst->fs_path, strlen(fst->fs_path));
+ }
+ strmode(sem.mode, mode);
+ }
+ sol_map_key(&sol_stream, "mode", 4);
+ sol_string(&sol_stream, mode, strlen(mode));
+ sol_map_key(&sol_stream, "sem", 3);
+ sol_integer(&sol_stream, sem.value);
+ }
+ else
+#endif
+ {
+ if (nflg) {
+ printf(" ");
+ (void)snprintf(mode, sizeof(mode), "%o", sem.mode);
+ } else {
+ printf(" %-15s", fst->fs_path != NULL ? fst->fs_path : "-");
+ strmode(sem.mode, mode);
+ }
+ printf(" %10s %6u", mode, sem.value);
}
- printf(" %10s %6u", mode, sem.value);
print_access_flags(fst->fs_fflags);
}
@@ -462,17 +660,39 @@
error = procstat_get_shm_info(procstat, fst, &shm, errbuf);
if (error != 0) {
- printf("* error");
+ if (!Oflg) printf("* error");
return;
}
- if (nflg) {
- printf(" ");
- (void)snprintf(mode, sizeof(mode), "%o", shm.mode);
- } else {
- printf(" %-15s", fst->fs_path != NULL ? fst->fs_path : "-");
- strmode(shm.mode, mode);
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ if (nflg) {
+ (void)snprintf(mode, sizeof(mode), "%o", shm.mode);
+ }
+ else {
+ if (fst->fs_path) {
+ sol_map_key(&sol_stream, "path", 4);
+ sol_string(&sol_stream, fst->fs_path, strlen(fst->fs_path));
+ }
+ strmode(shm.mode, mode);
+ }
+ sol_map_key(&sol_stream, "mode", 4);
+ sol_string(&sol_stream, mode, strlen(mode));
+ sol_map_key(&sol_stream, "shmsize", 7);
+ sol_integer(&sol_stream, shm.size);
+ }
+ else
+#endif
+ {
+ if (nflg) {
+ printf(" ");
+ (void)snprintf(mode, sizeof(mode), "%o", shm.mode);
+ } else {
+ printf(" %-15s", fst->fs_path != NULL ? fst->fs_path : "-");
+ strmode(shm.mode, mode);
+ }
+ printf(" %10s %6ju", mode, shm.size);
}
- printf(" %10s %6ju", mode, shm.size);
print_access_flags(fst->fs_fflags);
}
@@ -494,14 +714,36 @@
else if (vn.vn_type == PS_FST_VTYPE_VNON)
badtype = "none";
if (badtype != NULL) {
- printf(" - - %10s -", badtype);
+#if defined(SOL_ON)
+ if (Oflg) {
+ sol_map_key(&sol_stream, "mode", 4);
+ sol_string(&sol_stream, badtype, strlen(badtype));
+ }
+ else
+#endif
+ printf(" - - %10s -", badtype);
return;
}
- if (nflg)
- printf(" %#5jx", (uintmax_t)vn.vn_fsid);
- else if (vn.vn_mntdir != NULL)
- (void)printf(" %-8s", vn.vn_mntdir);
+#if defined(SOL_ON)
+ if (Oflg) {
+ if (nflg) {
+ sol_map_key(&sol_stream, "dev", 3);
+ sol_integer(&sol_stream, vn.vn_fsid); // TODO hex?
+ }
+ else if (vn.vn_mntdir != NULL) {
+ sol_map_key(&sol_stream, "mount", 5);
+ sol_string(&sol_stream, vn.vn_mntdir, strlen(vn.vn_mntdir));
+ }
+ }
+ else
+#endif
+ {
+ if (nflg)
+ printf(" %#5jx", (uintmax_t)vn.vn_fsid);
+ else if (vn.vn_mntdir != NULL)
+ (void)printf(" %-8s", vn.vn_mntdir);
+ }
/*
* Print access mode.
@@ -511,16 +753,48 @@
else {
strmode(vn.vn_mode, mode);
}
- (void)printf(" %6jd %10s", (intmax_t)vn.vn_fileid, mode);
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ sol_map_key(&sol_stream, "inode", 5);
+ sol_integer(&sol_stream, vn.vn_fileid);
- 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);
- else {
- printf(" %6s", vn.vn_devname);
- }
- } else
- printf(" %6ju", (uintmax_t)vn.vn_size);
+ sol_map_key(&sol_stream, "mode", 4);
+ sol_string(&sol_stream, mode, strlen(mode));
+ }
+ else
+#endif
+ (void)printf(" %6jd %10s", (intmax_t)vn.vn_fileid, mode);
+
+#if defined(SOL_ON)
+ if (Oflg)
+ {
+ if (vn.vn_type == PS_FST_VTYPE_VBLK || vn.vn_type == PS_FST_VTYPE_VCHR) {
+ if (nflg || !*vn.vn_devname) {
+ sol_map_key(&sol_stream, "dev", 3);
+ sol_integer(&sol_stream, vn.vn_dev); // TODO hex?
+ }
+ else {
+ sol_map_key(&sol_stream, "devname", 7);
+ sol_string(&sol_stream, vn.vn_devname, strlen(vn.vn_devname));
+ }
+ } else
+ sol_map_key(&sol_stream, "size", 4);
+ sol_integer(&sol_stream, vn.vn_size);
+ }
+ else
+ {
+#endif
+ 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);
+ }
+ else {
+ printf(" %6s", vn.vn_devname);
+ }
+ } else
+ printf(" %6ju", (uintmax_t)vn.vn_size);
+ }
print_access_flags(fst->fs_fflags);
}
@@ -534,7 +808,14 @@
strcat(rw, "r");
if (flags & PS_FST_FFLAG_WRITE)
strcat(rw, "w");
- printf(" %2s", rw);
+#if defined(SOL_ON)
+ if (Oflg) {
+ sol_map_key(&sol_stream, "r/w", 3);
+ sol_string(&sol_stream, rw, strlen(rw));
+ }
+ else
+#endif
+ printf(" %2s", rw);
}
int
@@ -562,6 +843,6 @@
usage(void)
{
(void)fprintf(stderr,
- "usage: fstat [-fmnv] [-M core] [-N system] [-p pid] [-u user] [file ...]\n");
+ "usage: fstat [-fmnv] [-M core] [-N system] [-p pid] [-u user] [-O] [file ...]\n");
exit(1);
}
More information about the svn-soc-all
mailing list