diff options
Diffstat (limited to 'monitor')
-rw-r--r-- | monitor/hmp.c | 32 | ||||
-rw-r--r-- | monitor/misc.c | 18 | ||||
-rw-r--r-- | monitor/monitor-internal.h | 7 |
3 files changed, 53 insertions, 4 deletions
diff --git a/monitor/hmp.c b/monitor/hmp.c index d50c3124e1..b20737e63c 100644 --- a/monitor/hmp.c +++ b/monitor/hmp.c @@ -26,6 +26,7 @@ #include <dirent.h> #include "hw/qdev-core.h" #include "monitor-internal.h" +#include "monitor/hmp.h" #include "qapi/error.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qnum.h" @@ -1061,6 +1062,31 @@ fail: return NULL; } +static void hmp_info_human_readable_text(Monitor *mon, + HumanReadableText *(*handler)(Error **)) +{ + Error *err = NULL; + g_autoptr(HumanReadableText) info = handler(&err); + + if (hmp_handle_error(mon, err)) { + return; + } + + monitor_printf(mon, "%s", info->human_readable_text); +} + +static void handle_hmp_command_exec(Monitor *mon, + const HMPCommand *cmd, + QDict *qdict) +{ + if (cmd->cmd_info_hrt) { + hmp_info_human_readable_text(mon, + cmd->cmd_info_hrt); + } else { + cmd->cmd(mon, qdict); + } +} + typedef struct HandleHmpCommandCo { Monitor *mon; const HMPCommand *cmd; @@ -1071,7 +1097,7 @@ typedef struct HandleHmpCommandCo { static void handle_hmp_command_co(void *opaque) { HandleHmpCommandCo *data = opaque; - data->cmd->cmd(data->mon, data->qdict); + handle_hmp_command_exec(data->mon, data->cmd, data->qdict); monitor_set_cur(qemu_coroutine_self(), NULL); data->done = true; } @@ -1089,7 +1115,7 @@ void handle_hmp_command(MonitorHMP *mon, const char *cmdline) return; } - if (!cmd->cmd) { + if (!cmd->cmd && !cmd->cmd_info_hrt) { /* FIXME: is it useful to try autoload modules here ??? */ monitor_printf(&mon->common, "Command \"%.*s\" is not available.\n", (int)(cmdline - cmd_start), cmd_start); @@ -1109,7 +1135,7 @@ void handle_hmp_command(MonitorHMP *mon, const char *cmdline) if (!cmd->coroutine) { /* old_mon is non-NULL when called from qmp_human_monitor_command() */ Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(), &mon->common); - cmd->cmd(&mon->common, qdict); + handle_hmp_command_exec(&mon->common, cmd, qdict); monitor_set_cur(qemu_coroutine_self(), old_mon); } else { HandleHmpCommandCo data = { diff --git a/monitor/misc.c b/monitor/misc.c index c2d227a07c..0e124044d0 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -1964,7 +1964,7 @@ void monitor_register_hmp(const char *name, bool info, while (table->name != NULL) { if (strcmp(table->name, name) == 0) { - g_assert(table->cmd == NULL); + g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL); table->cmd = cmd; return; } @@ -1973,6 +1973,22 @@ void monitor_register_hmp(const char *name, bool info, g_assert_not_reached(); } +void monitor_register_hmp_info_hrt(const char *name, + HumanReadableText *(*handler)(Error **errp)) +{ + HMPCommand *table = hmp_info_cmds; + + while (table->name != NULL) { + if (strcmp(table->name, name) == 0) { + g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL); + table->cmd_info_hrt = handler; + return; + } + table++; + } + g_assert_not_reached(); +} + void monitor_init_globals(void) { monitor_init_globals_core(); diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index 9c3a09cb01..3da3f86c6a 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -74,6 +74,13 @@ typedef struct HMPCommand { const char *help; const char *flags; /* p=preconfig */ void (*cmd)(Monitor *mon, const QDict *qdict); + /* + * If implementing a command that takes no arguments and simply + * prints formatted data, then leave @cmd NULL, and then set + * @cmd_info_hrt to the corresponding QMP handler that returns + * the formatted text. + */ + HumanReadableText *(*cmd_info_hrt)(Error **errp); bool coroutine; /* * @sub_table is a list of 2nd level of commands. If it does not exist, |