extern void add_command(const cmdinfo_t *ci);
extern void add_user_command(char *optarg);
+extern void add_oneshot_user_command(char *optarg);
extern void add_command_iterator(iterfunc_t func);
extern void add_check_command(checkfunc_t cf);
usage(void)
{
fprintf(stderr,
- _("Usage: %s [-adfinrRstVx] [-m mode] [-p prog] [-c cmd]... file\n"),
+_("Usage: %s [-adfinrRstVx] [-m mode] [-p prog] [[-c|-C] cmd]... file\n"),
progname);
exit(1);
}
pagesize = getpagesize();
gettimeofday(&stopwatch, NULL);
- while ((c = getopt(argc, argv, "ac:dFfim:p:nrRstTVx")) != EOF) {
+ while ((c = getopt(argc, argv, "ac:C:dFfim:p:nrRstTVx")) != EOF) {
switch (c) {
case 'a':
flags |= IO_APPEND;
case 'c':
add_user_command(optarg);
break;
+ case 'C':
+ add_oneshot_user_command(optarg);
+ break;
case 'd':
flags |= IO_DIRECT;
break;
static iterfunc_t iter_func;
static checkfunc_t check_func;
-static int ncmdline;
-static char **cmdline;
+
+struct cmdline {
+ char *cmdline;
+ bool iterate;
+};
+
+static int ncmdline;
+struct cmdline *cmdline;
static int
compare(const void *a, const void *b)
add_user_command(char *optarg)
{
ncmdline++;
- cmdline = realloc(cmdline, sizeof(char*) * (ncmdline));
+ cmdline = realloc(cmdline, sizeof(struct cmdline) * (ncmdline));
+ if (!cmdline) {
+ perror("realloc");
+ exit(1);
+ }
+ cmdline[ncmdline-1].cmdline = optarg;
+ cmdline[ncmdline-1].iterate = true;
+
+}
+
+void
+add_oneshot_user_command(char *optarg)
+{
+ ncmdline++;
+ cmdline = realloc(cmdline, sizeof(struct cmdline) * (ncmdline));
if (!cmdline) {
perror("realloc");
exit(1);
}
- cmdline[ncmdline-1] = optarg;
+ cmdline[ncmdline-1].cmdline = optarg;
+ cmdline[ncmdline-1].iterate = false;
}
/*
/* command line mode */
for (i = 0; !done && i < ncmdline; i++) {
- input = strdup(cmdline[i]);
+ input = strdup(cmdline[i].cmdline);
if (!input) {
fprintf(stderr,
_("cannot strdup command '%s': %s\n"),
- cmdline[i], strerror(errno));
+ cmdline[i].cmdline, strerror(errno));
exit(1);
}
- done = process_input(input, true);
+ done = process_input(input, cmdline[i].iterate);
}
free(cmdline);
return;
.B \-c
.I cmd
] ... [
+.B \-C
+.I cmd
+] ... [
.B \-p
.I prog
]
-.I file
+.I [ file ]
.br
.B xfs_io \-V
.SH DESCRIPTION
for manipulating files, but also cover all of the XFS extensions (such
as space preallocation, additional inode flags, etc).
.SH OPTIONS
+.B xfs_io
+commands may be run interactively (the default) or as arguments on the
+command line.
+Interactive mode always runs commands on the current open file, whilst commands
+run from the command line may be repeated on all open files rather than just the current
+open file.
+In general, open file iteration will occur for commands that operate on file
+content or state. In contrast, commands that operate on filesystem or
+system-wide state will only be run on the current file regardless of how many
+files are currently open.
+Multiple arguments may be given on the command line and they are run in the
+sequence given. The program exits one all commands have
+been run.
.TP 1.0i
.BI \-c " cmd"
-.B xfs_io
-commands may be run interactively (the default) or as arguments on
-the command line. Multiple
+Run the specified command on all currently open files.
+To maintain compatibility with historical usage, commands that can not be run on
+all open files will still be run but only execute once on the current open file.
+Multiple
+.B \-c
+arguments may be given and may be interleaved on the command line in any order
+with
+.B \-C
+commands.
+.TP
+.BI \-C " cmd"
+Run the specified command only on the current open file.
+Multiple
+.B \-C
+arguments may be given and may be interleaved on the command line in any order
+with
.B \-c
-arguments may be given. The commands are run in the sequence given,
-then the program exits.
+commands.
.TP
.BI \-p " prog"
Set the program name for prompts and some error messages,