Page MenuHomeFreeBSD

D50699.id158010.diff
No OneTemporary

D50699.id158010.diff

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,12 +37,14 @@
#include <err.h>
#include <fcntl.h>
#include <libprocstat.h>
+#include <libxo/xo.h>
#include <limits.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sysexits.h>
#include <unistd.h>
@@ -107,6 +109,7 @@
static int flags = 0; /* Option flags. */
static void printflags(struct consumer *consumer);
+static int str2sig(const char *str);
static void usage(void) __dead2;
static int addfile(const char *path, struct reqfile *reqfile);
static void dofiles(struct procstat *procstat, struct kinfo_proc *kp,
@@ -115,8 +118,7 @@
static void
usage(void)
{
-
- fprintf(stderr,
+ xo_error(
"usage: fuser [-cfhkmu] [-M core] [-N system] [-s signal] file ...\n");
exit(EX_USAGE);
}
@@ -125,14 +127,14 @@
printflags(struct consumer *cons)
{
unsigned int i;
-
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 +147,7 @@
assert(path);
if (stat(path, &sb) != 0) {
- warn("%s", path);
+ xo_warn("%s", path);
return (1);
}
reqfile->fileid = sb.st_ino;
@@ -162,10 +164,14 @@
struct kinfo_proc *procs;
struct procstat *procstat;
struct reqfile *reqfiles;
- char *nlistf, *memf;
+ char *ep, *nlistf, *memf;
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;
@@ -197,8 +203,17 @@
flags |= KFLAG;
break;
case 's':
- if (str2sig(optarg, &sig) != 0)
- errx(EX_USAGE, "invalid signal: %s", optarg);
+ if (isdigit(*optarg)) {
+ sig = strtol(optarg, &ep, 10);
+ if (*ep != '\0' || sig < 0 || sig >= sys_nsig)
+ xo_errx(EX_USAGE, "illegal signal number" ": %s",
+ optarg);
+ } else {
+ sig = str2sig(optarg);
+ if (sig < 0)
+ xo_errx(EX_USAGE, "illegal signal name: "
+ "%s", optarg);
+ }
break;
case 'h':
/* PASSTHROUGH */
@@ -219,23 +234,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 +259,35 @@
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);
}
@@ -294,13 +317,13 @@
break;
}
else if (reqfiles[i].fsid == vn.vn_fsid &&
- reqfiles[i].fileid == vn.vn_fileid) {
+ reqfiles[i].fileid == vn.vn_fileid) {
break;
}
else if (!(flags & FFLAG) &&
- (vn.vn_type == PS_FST_VTYPE_VCHR ||
- vn.vn_type == PS_FST_VTYPE_VBLK) &&
- vn.vn_fsid == reqfiles[i].fileid) {
+ (vn.vn_type == PS_FST_VTYPE_VCHR ||
+ vn.vn_type == PS_FST_VTYPE_VBLK) &&
+ vn.vn_fsid == reqfiles[i].fileid) {
break;
}
}
@@ -325,7 +348,7 @@
*/
cons = calloc(1, sizeof(struct consumer));
if (cons == NULL) {
- warn("malloc()");
+ xo_warn("malloc()");
continue;
}
cons->uid = kp->ki_uid;
@@ -337,3 +360,20 @@
}
procstat_freefiles(procstat, head);
}
+
+/*
+ * Returns signal number for it's string representation.
+ */
+static int
+str2sig(const char *str)
+{
+ int i;
+
+ if (!strncasecmp(str, "SIG", 3))
+ str += 3;
+ for (i = 1; i < sys_nsig; i++) {
+ if (!strcasecmp(sys_signame[i], str))
+ return (i);
+ }
+ return (-1);
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 8, 5:05 PM (15 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28476001
Default Alt Text
D50699.id158010.diff (6 KB)

Event Timeline