vsh: Add support for commands with more return values

Add a new handler callback for command handlers which will want to
return more than just EXIT_SUCCESS/EXIT_FAILURE.

The new handler allows returning integers. Any negative values are
converted to EXIT_FAILURE, other values are returned as reported in
cases where we forward the command state (non-interactive usage) as
return value of the virt shell program.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa
2025-06-12 10:17:03 +02:00
parent 10c646993d
commit 71e276ed1d
2 changed files with 21 additions and 5 deletions
+20 -5
View File
@@ -293,7 +293,7 @@ vshCmddefCheckInternals(vshControl *ctl,
return -1;
}
if (cmd->handler) {
if (cmd->handler || cmd->handler_rv) {
vshError(ctl, _("command '%1$s' has handler set"), cmd->name);
return -1;
}
@@ -323,6 +323,11 @@ vshCmddefCheckInternals(vshControl *ctl,
return -1;
}
if (!!cmd->handler + !!cmd->handler_rv != 1) {
vshError(ctl, _("command '%1$s' must have exactly one of the handler callbacks set"), cmd->name);
return -1;
}
if (!cmd->opts)
return 0;
@@ -1350,6 +1355,9 @@ vshBlockJobOptionBandwidth(vshControl *ctl,
* which return boolean are converted as:
* true -> EXIT_SUCCESS
* false -> EXIT_FAILURE
* Return values from command handlers returning integers are converted as:
* '< 0' -> EXIT_FAILURE
* others -> use value returned by handler callback.
*/
int
vshCommandRun(vshControl *ctl,
@@ -1366,10 +1374,17 @@ vshCommandRun(vshControl *ctl,
if ((cmd->def->flags & VSH_CMD_FLAG_NOCONNECT) ||
(hooks && hooks->connHandler && hooks->connHandler(ctl))) {
if (cmd->def->handler(ctl, cmd))
ret = EXIT_SUCCESS;
else
ret = EXIT_FAILURE;
if (cmd->def->handler_rv) {
ret = cmd->def->handler_rv(ctl, cmd);
if (ret < 0)
ret = EXIT_FAILURE;
} else {
if (cmd->def->handler(ctl, cmd))
ret = EXIT_SUCCESS;
else
ret = EXIT_FAILURE;
}
} else {
/* connection is not usable, return error */
ret = EXIT_FAILURE;
+1
View File
@@ -167,6 +167,7 @@ enum {
struct _vshCmdDef {
const char *name; /* name of command, or NULL for list end */
bool (*handler) (vshControl *, const vshCmd *); /* command handler */
int (*handler_rv) (vshControl *, const vshCmd *); /* command handler - allows return codes */
const vshCmdOptDef *opts; /* definition of command options */
const vshCmdInfo *info; /* details about command */
unsigned int flags; /* bitwise OR of VSH_CMD_FLAG */