@@ -20,7 +20,12 @@
#include <sys/time.h>
-#define CMD_FLAG_GLOBAL (1<<31) /* don't iterate "args" */
+/*
+ * A "oneshot" command ony runs once per command execution. It does
+ * not iterate the command args function callout and so can be used
+ * for functions like "help" that should only ever be run once.
+ */
+#define CMD_FLAG_ONESHOT (1<<31)
#define CMD_FLAG_FOREIGN_OK (1<<30) /* command not restricted to XFS */
typedef int (*cfunc_t)(int argc, char **argv);
@@ -104,7 +104,7 @@ file_init(void)
print_cmd.argmin = 0;
print_cmd.argmax = 0;
print_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK |
- CMD_FLAG_GLOBAL;
+ CMD_FLAG_ONESHOT;
print_cmd.oneline = _("list current open files and memory mappings");
add_command(&file_cmd);
@@ -104,7 +104,7 @@ static int
init_check_command(
const cmdinfo_t *ct)
{
- if (ct->flags & CMD_FLAG_GLOBAL)
+ if (ct->flags & CMD_FLAG_ONESHOT)
return 1;
if (!file && !(ct->flags & CMD_NOFILE_OK)) {
@@ -124,10 +124,20 @@ add_user_command(char *optarg)
cmdline[ncmdline-1] = optarg;
}
+/*
+ * To detect one-shot commands, they will return a negative index. If we
+ * get a negative index on entry, we've already run the one-shot command,
+ * so we abort straight away.
+ */
static int
args_command(
- int index)
+ const cmdinfo_t *ct,
+ int index)
{
+ if (index < 0)
+ return 0;
+ if (ct->flags & CMD_FLAG_ONESHOT)
+ return -1;
if (args_func)
return args_func(index);
return 0;
@@ -160,13 +170,9 @@ command_loop(void)
if (c) {
ct = find_command(v[0]);
if (ct) {
- if (ct->flags & CMD_FLAG_GLOBAL)
+ j = 0;
+ while (!done && (j = args_command(ct, j)))
done = command(ct, c, v);
- else {
- j = 0;
- while (!done && (j = args_command(j)))
- done = command(ct, c, v);
- }
} else
fprintf(stderr, _("command \"%s\" not found\n"),
v[0]);
@@ -89,7 +89,7 @@ help_init(void)
help_cmd.cfunc = help_f;
help_cmd.argmin = 0;
help_cmd.argmax = 1;
- help_cmd.flags = CMD_FLAG_GLOBAL | CMD_ALL_FSTYPES;
+ help_cmd.flags = CMD_FLAG_ONESHOT | CMD_ALL_FSTYPES;
help_cmd.args = _("[command]");
help_cmd.oneline = _("help for one or all commands");
@@ -39,7 +39,7 @@ quit_init(void)
quit_cmd.cfunc = quit_f;
quit_cmd.argmin = -1;
quit_cmd.argmax = -1;
- quit_cmd.flags = CMD_FLAG_GLOBAL | CMD_ALL_FSTYPES;
+ quit_cmd.flags = CMD_FLAG_ONESHOT | CMD_ALL_FSTYPES;
quit_cmd.oneline = _("exit the program");
add_command(&quit_cmd);
@@ -141,7 +141,7 @@ path_init(void)
path_cmd.cfunc = path_f;
path_cmd.argmin = 0;
path_cmd.argmax = 1;
- path_cmd.flags = CMD_FLAG_GLOBAL | CMD_FLAG_FOREIGN_OK;
+ path_cmd.flags = CMD_FLAG_ONESHOT | CMD_FLAG_FOREIGN_OK;
path_cmd.oneline = _("set current path, or show the list of paths");
print_cmd.name = "print";
@@ -149,7 +149,7 @@ path_init(void)
print_cmd.cfunc = print_f;
print_cmd.argmin = 0;
print_cmd.argmax = 0;
- print_cmd.flags = CMD_FLAG_GLOBAL | CMD_FLAG_FOREIGN_OK;
+ print_cmd.flags = CMD_FLAG_ONESHOT | CMD_FLAG_FOREIGN_OK;
print_cmd.oneline = _("list known mount points and projects");
if (expert)
@@ -770,7 +770,7 @@ report_init(void)
report_cmd.args = _("[-bir] [-gpu] [-ahnt] [-f file]");
report_cmd.oneline = _("report filesystem quota information");
report_cmd.help = report_help;
- report_cmd.flags = CMD_FLAG_GLOBAL | CMD_FLAG_FOREIGN_OK;
+ report_cmd.flags = CMD_FLAG_ONESHOT | CMD_FLAG_FOREIGN_OK;
if (expert) {
add_command(&dump_cmd);