diff --git a/usr.bin/fstat/fuser.1 b/usr.bin/fstat/fuser.1 --- a/usr.bin/fstat/fuser.1 +++ b/usr.bin/fstat/fuser.1 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 18, 2020 +.Dd June 3, 2025 .Dt FUSER 1 .Os .Sh NAME @@ -30,6 +30,7 @@ .Nd list IDs of all processes that have one or more files open .Sh SYNOPSIS .Nm +.Op Fl -libxo .Op Fl cfkmu .Op Fl M Ar core .Op Fl N Ar system @@ -54,6 +55,13 @@ .Pp The following options are available: .Bl -tag -width indent +.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 c Treat files as mount points and report on any files open in the file system. .It Fl f @@ -120,6 +128,8 @@ .Xr fstat 1 , .Xr ps 1 , .Xr systat 1 , +.Xr libxo 3 , +.Xr xo_parse_args 3 , .Xr iostat 8 , .Xr pstat 8 , .Xr vmstat 8 diff --git a/usr.bin/fstat/fuser.c b/usr.bin/fstat/fuser.c --- a/usr.bin/fstat/fuser.c +++ b/usr.bin/fstat/fuser.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -115,8 +116,7 @@ static void usage(void) { - - fprintf(stderr, + xo_error( "usage: fuser [-cfhkmu] [-M core] [-N system] [-s signal] file ...\n"); exit(EX_USAGE); } @@ -129,10 +129,10 @@ assert(cons); for (i = 0; i < NUFLAGS; i++) if ((cons->uflags & uflags[i].flag) != 0) - fputc(uflags[i].ch, stderr); + xo_emit_err("{:uflag/%c}", uflags[i].ch); for (i = 0; i < NFFLAGS; i++) if ((cons->flags & fflags[i].flag) != 0) - fputc(fflags[i].ch, stderr); + xo_emit_err("{:fflag/%c}", fflags[i].ch); } /* @@ -145,7 +145,7 @@ assert(path); if (stat(path, &sb) != 0) { - warn("%s", path); + xo_warn("%s", path); return (1); } reqfile->fileid = sb.st_ino; @@ -166,6 +166,10 @@ int ch, sig; unsigned int i, cnt, nfiles; + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(EX_USAGE); + sig = SIGKILL; /* Default to kill. */ nlistf = NULL; memf = NULL; @@ -198,7 +202,7 @@ break; case 's': if (str2sig(optarg, &sig) != 0) - errx(EX_USAGE, "invalid signal: %s", optarg); + xo_errx(EX_USAGE, "invalid signal: %s", optarg); break; case 'h': /* PASSTHROUGH */ @@ -219,23 +223,23 @@ */ reqfiles = malloc(argc * sizeof(struct reqfile)); if (reqfiles == NULL) - err(EX_OSERR, "malloc()"); + xo_err(EX_OSERR, "malloc()"); nfiles = 0; while (argc--) if (!addfile(*(argv++), &reqfiles[nfiles])) nfiles++; if (nfiles == 0) - errx(EX_IOERR, "files not accessible"); + xo_errx(EX_IOERR, "files not accessible"); if (memf != NULL) procstat = procstat_open_kvm(nlistf, memf); else procstat = procstat_open_sysctl(); if (procstat == NULL) - errx(1, "procstat_open()"); + xo_errx(1, "procstat_open()"); procs = procstat_getprocs(procstat, KERN_PROC_PROC, 0, &cnt); if (procs == NULL) - errx(1, "procstat_getprocs()"); + xo_errx(1, "procstat_getprocs()"); /* * Walk through process table and look for matching files. @@ -244,27 +248,34 @@ if (procs[i].ki_stat != SZOMB) dofiles(procstat, &procs[i], reqfiles, nfiles); + xo_open_container("files"); for (i = 0; i < nfiles; i++) { - fprintf(stderr, "%s:", reqfiles[i].name); + xo_error("%s:", reqfiles[i].name); fflush(stderr); - STAILQ_FOREACH(consumer, &reqfiles[i].consumers, next) { - if (consumer->flags != 0) { - fprintf(stdout, "%6d", consumer->pid); - fflush(stdout); - printflags(consumer); - if ((flags & UFLAG) != 0) - fprintf(stderr, "(%s)", - user_from_uid(consumer->uid, 0)); - if ((flags & KFLAG) != 0) - kill(consumer->pid, sig); - fflush(stderr); + xo_open_list("consumers"); + STAILQ_FOREACH(consumer, &reqfiles[i].consumers, next) { + if (consumer->flags != 0) { + xo_open_instance("consumer"); + xo_emit("{:pid/%6d/%d}", consumer->pid); + xo_flush(); + printflags(consumer); + if ((flags & UFLAG) != 0) + xo_error("(%s)", + user_from_uid(consumer->uid, 0)); + if ((flags & KFLAG) != 0) + kill(consumer->pid, sig); + fflush(stderr); + xo_close_instance("consumer"); + } } - } - (void)fprintf(stderr, "\n"); + xo_close_list("consumers"); + xo_emit("{D:/\n}"); } + xo_close_container("files"); procstat_freeprocs(procstat, procs); procstat_close(procstat); free(reqfiles); + xo_finish(); return (0); } @@ -325,7 +336,7 @@ */ cons = calloc(1, sizeof(struct consumer)); if (cons == NULL) { - warn("malloc()"); + xo_warn("malloc()"); continue; } cons->uid = kp->ki_uid;