@@ -3732,12 +3732,13 @@ static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
{
- QObject *req, *rsp = NULL, *id = NULL;
- QDict *qdict = NULL;
+ QObject *req, *rsp, *id = NULL;
+ QDict *qdict, *rqdict = qdict_new();
const char *cmd_name;
Monitor *mon = cur_mon;
Error *err = NULL;
+ rsp = QOBJECT(rqdict);
req = json_parser_parse_err(tokens, NULL, &err);
if (err || !req || qobject_type(req) != QTYPE_QDICT) {
if (!err) {
@@ -3752,8 +3753,11 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
}
id = qdict_get(qdict, "id");
- qobject_incref(id);
- qdict_del(qdict, "id");
+ if (id) {
+ qobject_incref(id);
+ qdict_del(qdict, "id");
+ qdict_put_obj(rqdict, "id", id);
+ }
cmd_name = qdict_get_str(qdict, "execute");
trace_handle_qmp_command(mon, cmd_name);
@@ -3762,27 +3766,19 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
goto err_out;
}
- rsp = qmp_dispatch(req);
+ rsp = qmp_dispatch(req, rqdict);
err_out:
if (err) {
- qdict = qdict_new();
- qdict_put_obj(qdict, "error", qmp_build_error_object(err));
+ qdict_put_obj(rqdict, "error", qmp_build_error_object(err));
error_free(err);
- rsp = QOBJECT(qdict);
}
if (rsp) {
- if (id) {
- qdict_put_obj(qobject_to_qdict(rsp), "id", id);
- id = NULL;
- }
-
monitor_json_emitter(mon, rsp);
}
- qobject_decref(id);
- qobject_decref(rsp);
+ QDECREF(rqdict);
qobject_decref(req);
}
@@ -116,15 +116,14 @@ QObject *qmp_build_error_object(Error *err)
error_get_pretty(err));
}
-QObject *qmp_dispatch(QObject *request)
+QObject *qmp_dispatch(QObject *request, QDict *rsp)
{
Error *err = NULL;
QObject *ret;
- QDict *rsp;
ret = do_qmp_dispatch(request, &err);
- rsp = qdict_new();
+ rsp = rsp ?: qdict_new();
if (err) {
qdict_put_obj(rsp, "error", qmp_build_error_object(err));
error_free(err);
@@ -555,7 +555,7 @@ static void process_command(GAState *s, QDict *req)
g_assert(req);
g_debug("processing command");
- rsp = qmp_dispatch(QOBJECT(req));
+ rsp = qmp_dispatch(QOBJECT(req), NULL);
if (rsp) {
ret = send_response(s, rsp);
if (ret) {
@@ -94,7 +94,7 @@ static void test_dispatch_cmd(void)
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
- resp = qmp_dispatch(QOBJECT(req));
+ resp = qmp_dispatch(QOBJECT(req), NULL);
assert(resp != NULL);
assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
@@ -111,7 +111,7 @@ static void test_dispatch_cmd_failure(void)
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
- resp = qmp_dispatch(QOBJECT(req));
+ resp = qmp_dispatch(QOBJECT(req), NULL);
assert(resp != NULL);
assert(qdict_haskey(qobject_to_qdict(resp), "error"));
@@ -125,7 +125,7 @@ static void test_dispatch_cmd_failure(void)
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
- resp = qmp_dispatch(QOBJECT(req));
+ resp = qmp_dispatch(QOBJECT(req), NULL);
assert(resp != NULL);
assert(qdict_haskey(qobject_to_qdict(resp), "error"));
@@ -139,7 +139,7 @@ static QObject *test_qmp_dispatch(QDict *req)
QDict *resp;
QObject *ret;
- resp_obj = qmp_dispatch(QOBJECT(req));
+ resp_obj = qmp_dispatch(QOBJECT(req), NULL);
assert(resp_obj);
resp = qobject_to_qdict(resp_obj);
assert(resp && !qdict_haskey(resp, "error"));
@@ -38,7 +38,7 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn,
QmpCommandOptions options);
void qmp_unregister_command(const char *name);
QmpCommand *qmp_find_command(const char *name);
-QObject *qmp_dispatch(QObject *request);
+QObject *qmp_dispatch(QObject *request, QDict *rsp);
void qmp_disable_command(const char *name);
void qmp_enable_command(const char *name);
bool qmp_command_is_enabled(const QmpCommand *cmd);
Give an optionnal qdict for the dispatch call to be used for the reply. The qemu monitor has the request "id" pre-filled, simplifying a bit the code. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> --- monitor.c | 26 +++++++++++--------------- qapi/qmp-dispatch.c | 5 ++--- qga/main.c | 2 +- tests/test-qmp-commands.c | 8 ++++---- include/qapi/qmp/dispatch.h | 2 +- 5 files changed, 19 insertions(+), 24 deletions(-)