Revision ab02ab2a

b/Makefile.objs
376 376
# qapi
377 377

  
378 378
qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o qapi-dealloc-visitor.o
379
qapi-nested-y += qmp-registry.o
379
qapi-nested-y += qmp-registry.o qmp-dispatch.o
380 380
qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
381 381

  
382 382
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
b/qapi/qmp-core.h
35 35

  
36 36
void qmp_register_command(const char *name, QmpCommandFunc *fn);
37 37
QmpCommand *qmp_find_command(const char *name);
38
QObject *qmp_dispatch(QObject *request);
38 39

  
39 40
#endif
41

  
b/qapi/qmp-dispatch.c
1
/*
2
 * Core Definitions for QAPI/QMP Dispatch
3
 *
4
 * Copyright IBM, Corp. 2011
5
 *
6
 * Authors:
7
 *  Anthony Liguori   <aliguori@us.ibm.com>
8
 *
9
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10
 * See the COPYING.LIB file in the top-level directory.
11
 *
12
 */
13

  
14
#include "qemu-objects.h"
15
#include "qapi/qmp-core.h"
16
#include "json-parser.h"
17
#include "error.h"
18
#include "error_int.h"
19
#include "qerror.h"
20

  
21
static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
22
{
23
    const QDictEntry *ent;
24
    const char *arg_name;
25
    const QObject *arg_obj;
26
    bool has_exec_key = false;
27
    QDict *dict = NULL;
28

  
29
    if (qobject_type(request) != QTYPE_QDICT) {
30
        error_set(errp, QERR_QMP_BAD_INPUT_OBJECT,
31
                  "request is not a dictionary");
32
        return NULL;
33
    }
34

  
35
    dict = qobject_to_qdict(request);
36

  
37
    for (ent = qdict_first(dict); ent;
38
         ent = qdict_next(dict, ent)) {
39
        arg_name = qdict_entry_key(ent);
40
        arg_obj = qdict_entry_value(ent);
41

  
42
        if (!strcmp(arg_name, "execute")) {
43
            if (qobject_type(arg_obj) != QTYPE_QSTRING) {
44
                error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute",
45
                          "string");
46
                return NULL;
47
            }
48
            has_exec_key = true;
49
        } else if (strcmp(arg_name, "arguments")) {
50
            error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
51
            return NULL;
52
        }
53
    }
54

  
55
    if (!has_exec_key) {
56
        error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");
57
        return NULL;
58
    }
59

  
60
    return dict;
61
}
62

  
63
static QObject *do_qmp_dispatch(QObject *request, Error **errp)
64
{
65
    const char *command;
66
    QDict *args, *dict;
67
    QmpCommand *cmd;
68
    QObject *ret = NULL;
69

  
70

  
71
    dict = qmp_dispatch_check_obj(request, errp);
72
    if (!dict || error_is_set(errp)) {
73
        return NULL;
74
    }
75

  
76
    command = qdict_get_str(dict, "execute");
77
    cmd = qmp_find_command(command);
78
    if (cmd == NULL) {
79
        error_set(errp, QERR_COMMAND_NOT_FOUND, command);
80
        return NULL;
81
    }
82

  
83
    if (!qdict_haskey(dict, "arguments")) {
84
        args = qdict_new();
85
    } else {
86
        args = qdict_get_qdict(dict, "arguments");
87
        QINCREF(args);
88
    }
89

  
90
    switch (cmd->type) {
91
    case QCT_NORMAL:
92
        cmd->fn(args, &ret, errp);
93
        if (!error_is_set(errp) && ret == NULL) {
94
            ret = QOBJECT(qdict_new());
95
        }
96
        break;
97
    }
98

  
99
    QDECREF(args);
100

  
101
    return ret;
102
}
103

  
104
QObject *qmp_dispatch(QObject *request)
105
{
106
    Error *err = NULL;
107
    QObject *ret;
108
    QDict *rsp;
109

  
110
    ret = do_qmp_dispatch(request, &err);
111

  
112
    rsp = qdict_new();
113
    if (err) {
114
        qdict_put_obj(rsp, "error", error_get_qobject(err));
115
        error_free(err);
116
    } else if (ret) {
117
        qdict_put_obj(rsp, "return", ret);
118
    } else {
119
        QDECREF(rsp);
120
        return NULL;
121
    }
122

  
123
    return QOBJECT(rsp);
124
}

Also available in: Unified diff