Date: Tue, 3 Jun 2014 13:22:02 GMT From: zkorchev@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r269005 - soc2014/zkorchev/freebsd_head/usr.bin/fstat Message-ID: <201406031322.s53DM2e5092466@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406031322.s53DM2e5092466>