xref: /qemu/monitor/hmp.c (revision 6ee7c82d)
1ed7bda5dSKevin Wolf /*
2ed7bda5dSKevin Wolf  * QEMU monitor
3ed7bda5dSKevin Wolf  *
4ed7bda5dSKevin Wolf  * Copyright (c) 2003-2004 Fabrice Bellard
5ed7bda5dSKevin Wolf  *
6ed7bda5dSKevin Wolf  * Permission is hereby granted, free of charge, to any person obtaining a copy
7ed7bda5dSKevin Wolf  * of this software and associated documentation files (the "Software"), to deal
8ed7bda5dSKevin Wolf  * in the Software without restriction, including without limitation the rights
9ed7bda5dSKevin Wolf  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10ed7bda5dSKevin Wolf  * copies of the Software, and to permit persons to whom the Software is
11ed7bda5dSKevin Wolf  * furnished to do so, subject to the following conditions:
12ed7bda5dSKevin Wolf  *
13ed7bda5dSKevin Wolf  * The above copyright notice and this permission notice shall be included in
14ed7bda5dSKevin Wolf  * all copies or substantial portions of the Software.
15ed7bda5dSKevin Wolf  *
16ed7bda5dSKevin Wolf  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17ed7bda5dSKevin Wolf  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18ed7bda5dSKevin Wolf  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19ed7bda5dSKevin Wolf  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20ed7bda5dSKevin Wolf  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21ed7bda5dSKevin Wolf  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22ed7bda5dSKevin Wolf  * THE SOFTWARE.
23ed7bda5dSKevin Wolf  */
24ed7bda5dSKevin Wolf 
25ed7bda5dSKevin Wolf #include "qemu/osdep.h"
26ed7bda5dSKevin Wolf #include <dirent.h>
27164dafd1SPaolo Bonzini #include "hw/qdev-core.h"
28ed7bda5dSKevin Wolf #include "monitor-internal.h"
29f9429c67SDaniel P. Berrangé #include "monitor/hmp.h"
30ed7bda5dSKevin Wolf #include "qapi/qmp/qdict.h"
31ed7bda5dSKevin Wolf #include "qapi/qmp/qnum.h"
32ed7bda5dSKevin Wolf #include "qemu/config-file.h"
33ed7bda5dSKevin Wolf #include "qemu/ctype.h"
34ed7bda5dSKevin Wolf #include "qemu/cutils.h"
35ed7bda5dSKevin Wolf #include "qemu/log.h"
36ed7bda5dSKevin Wolf #include "qemu/option.h"
37ed7bda5dSKevin Wolf #include "qemu/units.h"
38ed7bda5dSKevin Wolf #include "sysemu/block-backend.h"
39ed7bda5dSKevin Wolf #include "trace.h"
40ed7bda5dSKevin Wolf 
monitor_command_cb(void * opaque,const char * cmdline,void * readline_opaque)41ed7bda5dSKevin Wolf static void monitor_command_cb(void *opaque, const char *cmdline,
42ed7bda5dSKevin Wolf                                void *readline_opaque)
43ed7bda5dSKevin Wolf {
44ed7bda5dSKevin Wolf     MonitorHMP *mon = opaque;
45ed7bda5dSKevin Wolf 
46ed7bda5dSKevin Wolf     monitor_suspend(&mon->common);
47ed7bda5dSKevin Wolf     handle_hmp_command(mon, cmdline);
48ed7bda5dSKevin Wolf     monitor_resume(&mon->common);
49ed7bda5dSKevin Wolf }
50ed7bda5dSKevin Wolf 
monitor_read_command(MonitorHMP * mon,int show_prompt)51ed7bda5dSKevin Wolf void monitor_read_command(MonitorHMP *mon, int show_prompt)
52ed7bda5dSKevin Wolf {
53ed7bda5dSKevin Wolf     if (!mon->rs) {
54ed7bda5dSKevin Wolf         return;
55ed7bda5dSKevin Wolf     }
56ed7bda5dSKevin Wolf 
57ed7bda5dSKevin Wolf     readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
58ed7bda5dSKevin Wolf     if (show_prompt) {
59ed7bda5dSKevin Wolf         readline_show_prompt(mon->rs);
60ed7bda5dSKevin Wolf     }
61ed7bda5dSKevin Wolf }
62ed7bda5dSKevin Wolf 
monitor_read_password(MonitorHMP * mon,ReadLineFunc * readline_func,void * opaque)63ed7bda5dSKevin Wolf int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func,
64ed7bda5dSKevin Wolf                           void *opaque)
65ed7bda5dSKevin Wolf {
66ed7bda5dSKevin Wolf     if (mon->rs) {
67ed7bda5dSKevin Wolf         readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
68ed7bda5dSKevin Wolf         /* prompt is printed on return from the command handler */
69ed7bda5dSKevin Wolf         return 0;
70ed7bda5dSKevin Wolf     } else {
71ed7bda5dSKevin Wolf         monitor_printf(&mon->common,
72ed7bda5dSKevin Wolf                        "terminal does not support password prompting\n");
73ed7bda5dSKevin Wolf         return -ENOTTY;
74ed7bda5dSKevin Wolf     }
75ed7bda5dSKevin Wolf }
76ed7bda5dSKevin Wolf 
get_str(char * buf,int buf_size,const char ** pp)77ed7bda5dSKevin Wolf static int get_str(char *buf, int buf_size, const char **pp)
78ed7bda5dSKevin Wolf {
79ed7bda5dSKevin Wolf     const char *p;
80ed7bda5dSKevin Wolf     char *q;
81ed7bda5dSKevin Wolf     int c;
82ed7bda5dSKevin Wolf 
83ed7bda5dSKevin Wolf     q = buf;
84ed7bda5dSKevin Wolf     p = *pp;
85ed7bda5dSKevin Wolf     while (qemu_isspace(*p)) {
86ed7bda5dSKevin Wolf         p++;
87ed7bda5dSKevin Wolf     }
88ed7bda5dSKevin Wolf     if (*p == '\0') {
89ed7bda5dSKevin Wolf     fail:
90ed7bda5dSKevin Wolf         *q = '\0';
91ed7bda5dSKevin Wolf         *pp = p;
92ed7bda5dSKevin Wolf         return -1;
93ed7bda5dSKevin Wolf     }
94ed7bda5dSKevin Wolf     if (*p == '\"') {
95ed7bda5dSKevin Wolf         p++;
96ed7bda5dSKevin Wolf         while (*p != '\0' && *p != '\"') {
97ed7bda5dSKevin Wolf             if (*p == '\\') {
98ed7bda5dSKevin Wolf                 p++;
99ed7bda5dSKevin Wolf                 c = *p++;
100ed7bda5dSKevin Wolf                 switch (c) {
101ed7bda5dSKevin Wolf                 case 'n':
102ed7bda5dSKevin Wolf                     c = '\n';
103ed7bda5dSKevin Wolf                     break;
104ed7bda5dSKevin Wolf                 case 'r':
105ed7bda5dSKevin Wolf                     c = '\r';
106ed7bda5dSKevin Wolf                     break;
107ed7bda5dSKevin Wolf                 case '\\':
108ed7bda5dSKevin Wolf                 case '\'':
109ed7bda5dSKevin Wolf                 case '\"':
110ed7bda5dSKevin Wolf                     break;
111ed7bda5dSKevin Wolf                 default:
112ed7bda5dSKevin Wolf                     printf("unsupported escape code: '\\%c'\n", c);
113ed7bda5dSKevin Wolf                     goto fail;
114ed7bda5dSKevin Wolf                 }
115ed7bda5dSKevin Wolf                 if ((q - buf) < buf_size - 1) {
116ed7bda5dSKevin Wolf                     *q++ = c;
117ed7bda5dSKevin Wolf                 }
118ed7bda5dSKevin Wolf             } else {
119ed7bda5dSKevin Wolf                 if ((q - buf) < buf_size - 1) {
120ed7bda5dSKevin Wolf                     *q++ = *p;
121ed7bda5dSKevin Wolf                 }
122ed7bda5dSKevin Wolf                 p++;
123ed7bda5dSKevin Wolf             }
124ed7bda5dSKevin Wolf         }
125ed7bda5dSKevin Wolf         if (*p != '\"') {
126ed7bda5dSKevin Wolf             printf("unterminated string\n");
127ed7bda5dSKevin Wolf             goto fail;
128ed7bda5dSKevin Wolf         }
129ed7bda5dSKevin Wolf         p++;
130ed7bda5dSKevin Wolf     } else {
131ed7bda5dSKevin Wolf         while (*p != '\0' && !qemu_isspace(*p)) {
132ed7bda5dSKevin Wolf             if ((q - buf) < buf_size - 1) {
133ed7bda5dSKevin Wolf                 *q++ = *p;
134ed7bda5dSKevin Wolf             }
135ed7bda5dSKevin Wolf             p++;
136ed7bda5dSKevin Wolf         }
137ed7bda5dSKevin Wolf     }
138ed7bda5dSKevin Wolf     *q = '\0';
139ed7bda5dSKevin Wolf     *pp = p;
140ed7bda5dSKevin Wolf     return 0;
141ed7bda5dSKevin Wolf }
142ed7bda5dSKevin Wolf 
143ed7bda5dSKevin Wolf #define MAX_ARGS 16
144ed7bda5dSKevin Wolf 
free_cmdline_args(char ** args,int nb_args)145ed7bda5dSKevin Wolf static void free_cmdline_args(char **args, int nb_args)
146ed7bda5dSKevin Wolf {
147ed7bda5dSKevin Wolf     int i;
148ed7bda5dSKevin Wolf 
149ed7bda5dSKevin Wolf     assert(nb_args <= MAX_ARGS);
150ed7bda5dSKevin Wolf 
151ed7bda5dSKevin Wolf     for (i = 0; i < nb_args; i++) {
152ed7bda5dSKevin Wolf         g_free(args[i]);
153ed7bda5dSKevin Wolf     }
154ed7bda5dSKevin Wolf 
155ed7bda5dSKevin Wolf }
156ed7bda5dSKevin Wolf 
157ed7bda5dSKevin Wolf /*
158ed7bda5dSKevin Wolf  * Parse the command line to get valid args.
159ed7bda5dSKevin Wolf  * @cmdline: command line to be parsed.
160ed7bda5dSKevin Wolf  * @pnb_args: location to store the number of args, must NOT be NULL.
161ed7bda5dSKevin Wolf  * @args: location to store the args, which should be freed by caller, must
162ed7bda5dSKevin Wolf  *        NOT be NULL.
163ed7bda5dSKevin Wolf  *
164ed7bda5dSKevin Wolf  * Returns 0 on success, negative on failure.
165ed7bda5dSKevin Wolf  *
166ed7bda5dSKevin Wolf  * NOTE: this parser is an approximate form of the real command parser. Number
167ed7bda5dSKevin Wolf  *       of args have a limit of MAX_ARGS. If cmdline contains more, it will
168ed7bda5dSKevin Wolf  *       return with failure.
169ed7bda5dSKevin Wolf  */
parse_cmdline(const char * cmdline,int * pnb_args,char ** args)170ed7bda5dSKevin Wolf static int parse_cmdline(const char *cmdline,
171ed7bda5dSKevin Wolf                          int *pnb_args, char **args)
172ed7bda5dSKevin Wolf {
173ed7bda5dSKevin Wolf     const char *p;
174ed7bda5dSKevin Wolf     int nb_args, ret;
175ed7bda5dSKevin Wolf     char buf[1024];
176ed7bda5dSKevin Wolf 
177ed7bda5dSKevin Wolf     p = cmdline;
178ed7bda5dSKevin Wolf     nb_args = 0;
179ed7bda5dSKevin Wolf     for (;;) {
180ed7bda5dSKevin Wolf         while (qemu_isspace(*p)) {
181ed7bda5dSKevin Wolf             p++;
182ed7bda5dSKevin Wolf         }
183ed7bda5dSKevin Wolf         if (*p == '\0') {
184ed7bda5dSKevin Wolf             break;
185ed7bda5dSKevin Wolf         }
186ed7bda5dSKevin Wolf         if (nb_args >= MAX_ARGS) {
187ed7bda5dSKevin Wolf             goto fail;
188ed7bda5dSKevin Wolf         }
189ed7bda5dSKevin Wolf         ret = get_str(buf, sizeof(buf), &p);
190ed7bda5dSKevin Wolf         if (ret < 0) {
191ed7bda5dSKevin Wolf             goto fail;
192ed7bda5dSKevin Wolf         }
193ed7bda5dSKevin Wolf         args[nb_args] = g_strdup(buf);
194ed7bda5dSKevin Wolf         nb_args++;
195ed7bda5dSKevin Wolf     }
196ed7bda5dSKevin Wolf     *pnb_args = nb_args;
197ed7bda5dSKevin Wolf     return 0;
198ed7bda5dSKevin Wolf 
199ed7bda5dSKevin Wolf  fail:
200ed7bda5dSKevin Wolf     free_cmdline_args(args, nb_args);
201ed7bda5dSKevin Wolf     return -1;
202ed7bda5dSKevin Wolf }
203ed7bda5dSKevin Wolf 
204ed7bda5dSKevin Wolf /*
205ed7bda5dSKevin Wolf  * Can command @cmd be executed in preconfig state?
206ed7bda5dSKevin Wolf  */
cmd_can_preconfig(const HMPCommand * cmd)207ed7bda5dSKevin Wolf static bool cmd_can_preconfig(const HMPCommand *cmd)
208ed7bda5dSKevin Wolf {
209ed7bda5dSKevin Wolf     if (!cmd->flags) {
210ed7bda5dSKevin Wolf         return false;
211ed7bda5dSKevin Wolf     }
212ed7bda5dSKevin Wolf 
213ed7bda5dSKevin Wolf     return strchr(cmd->flags, 'p');
214ed7bda5dSKevin Wolf }
215ed7bda5dSKevin Wolf 
cmd_available(const HMPCommand * cmd)2164cd29274SPaolo Bonzini static bool cmd_available(const HMPCommand *cmd)
2174cd29274SPaolo Bonzini {
2182f181fbdSPaolo Bonzini     return phase_check(PHASE_MACHINE_READY) || cmd_can_preconfig(cmd);
2194cd29274SPaolo Bonzini }
2204cd29274SPaolo Bonzini 
help_cmd_dump_one(Monitor * mon,const HMPCommand * cmd,char ** prefix_args,int prefix_args_nb)221ed7bda5dSKevin Wolf static void help_cmd_dump_one(Monitor *mon,
222ed7bda5dSKevin Wolf                               const HMPCommand *cmd,
223ed7bda5dSKevin Wolf                               char **prefix_args,
224ed7bda5dSKevin Wolf                               int prefix_args_nb)
225ed7bda5dSKevin Wolf {
226ed7bda5dSKevin Wolf     int i;
227ed7bda5dSKevin Wolf 
2284cd29274SPaolo Bonzini     if (!cmd_available(cmd)) {
229ed7bda5dSKevin Wolf         return;
230ed7bda5dSKevin Wolf     }
231ed7bda5dSKevin Wolf 
232ed7bda5dSKevin Wolf     for (i = 0; i < prefix_args_nb; i++) {
233ed7bda5dSKevin Wolf         monitor_printf(mon, "%s ", prefix_args[i]);
234ed7bda5dSKevin Wolf     }
235ed7bda5dSKevin Wolf     monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help);
236ed7bda5dSKevin Wolf }
237ed7bda5dSKevin Wolf 
238ed7bda5dSKevin Wolf /* @args[@arg_index] is the valid command need to find in @cmds */
help_cmd_dump(Monitor * mon,const HMPCommand * cmds,char ** args,int nb_args,int arg_index)239ed7bda5dSKevin Wolf static void help_cmd_dump(Monitor *mon, const HMPCommand *cmds,
240ed7bda5dSKevin Wolf                           char **args, int nb_args, int arg_index)
241ed7bda5dSKevin Wolf {
242ed7bda5dSKevin Wolf     const HMPCommand *cmd;
243ed7bda5dSKevin Wolf     size_t i;
244ed7bda5dSKevin Wolf 
245ed7bda5dSKevin Wolf     /* No valid arg need to compare with, dump all in *cmds */
246ed7bda5dSKevin Wolf     if (arg_index >= nb_args) {
247ed7bda5dSKevin Wolf         for (cmd = cmds; cmd->name != NULL; cmd++) {
248ed7bda5dSKevin Wolf             help_cmd_dump_one(mon, cmd, args, arg_index);
249ed7bda5dSKevin Wolf         }
250ed7bda5dSKevin Wolf         return;
251ed7bda5dSKevin Wolf     }
252ed7bda5dSKevin Wolf 
253ed7bda5dSKevin Wolf     /* Find one entry to dump */
254ed7bda5dSKevin Wolf     for (cmd = cmds; cmd->name != NULL; cmd++) {
255ed7bda5dSKevin Wolf         if (hmp_compare_cmd(args[arg_index], cmd->name) &&
2564cd29274SPaolo Bonzini             cmd_available(cmd)) {
257ed7bda5dSKevin Wolf             if (cmd->sub_table) {
258ed7bda5dSKevin Wolf                 /* continue with next arg */
259ed7bda5dSKevin Wolf                 help_cmd_dump(mon, cmd->sub_table,
260ed7bda5dSKevin Wolf                               args, nb_args, arg_index + 1);
261ed7bda5dSKevin Wolf             } else {
262ed7bda5dSKevin Wolf                 help_cmd_dump_one(mon, cmd, args, arg_index);
263ed7bda5dSKevin Wolf             }
264ed7bda5dSKevin Wolf             return;
265ed7bda5dSKevin Wolf         }
266ed7bda5dSKevin Wolf     }
267ed7bda5dSKevin Wolf 
268ed7bda5dSKevin Wolf     /* Command not found */
269ed7bda5dSKevin Wolf     monitor_printf(mon, "unknown command: '");
270ed7bda5dSKevin Wolf     for (i = 0; i <= arg_index; i++) {
271ed7bda5dSKevin Wolf         monitor_printf(mon, "%s%s", args[i], i == arg_index ? "'\n" : " ");
272ed7bda5dSKevin Wolf     }
273ed7bda5dSKevin Wolf }
274ed7bda5dSKevin Wolf 
hmp_help_cmd(Monitor * mon,const char * name)2755ec92f2dSMarkus Armbruster void hmp_help_cmd(Monitor *mon, const char *name)
276ed7bda5dSKevin Wolf {
277ed7bda5dSKevin Wolf     char *args[MAX_ARGS];
278ed7bda5dSKevin Wolf     int nb_args = 0;
279ed7bda5dSKevin Wolf 
280ed7bda5dSKevin Wolf     /* 1. parse user input */
281ed7bda5dSKevin Wolf     if (name) {
282ed7bda5dSKevin Wolf         /* special case for log, directly dump and return */
283ed7bda5dSKevin Wolf         if (!strcmp(name, "log")) {
284ed7bda5dSKevin Wolf             const QEMULogItem *item;
285ed7bda5dSKevin Wolf             monitor_printf(mon, "Log items (comma separated):\n");
2863183bb3fSDongli Zhang             monitor_printf(mon, "%-15s %s\n", "none", "remove all logs");
287ed7bda5dSKevin Wolf             for (item = qemu_log_items; item->mask != 0; item++) {
2883183bb3fSDongli Zhang                 monitor_printf(mon, "%-15s %s\n", item->name, item->help);
289ed7bda5dSKevin Wolf             }
2903183bb3fSDongli Zhang #ifdef CONFIG_TRACE_LOG
2913183bb3fSDongli Zhang             monitor_printf(mon, "trace:PATTERN   enable trace events\n");
2923183bb3fSDongli Zhang             monitor_printf(mon, "\nUse \"log trace:help\" to get a list of "
2933183bb3fSDongli Zhang                            "trace events.\n\n");
2943183bb3fSDongli Zhang #endif
295ed7bda5dSKevin Wolf             return;
296ed7bda5dSKevin Wolf         }
297ed7bda5dSKevin Wolf 
298ed7bda5dSKevin Wolf         if (parse_cmdline(name, &nb_args, args) < 0) {
299ed7bda5dSKevin Wolf             return;
300ed7bda5dSKevin Wolf         }
301ed7bda5dSKevin Wolf     }
302ed7bda5dSKevin Wolf 
303ed7bda5dSKevin Wolf     /* 2. dump the contents according to parsed args */
304ed7bda5dSKevin Wolf     help_cmd_dump(mon, hmp_cmds, args, nb_args, 0);
305ed7bda5dSKevin Wolf 
306ed7bda5dSKevin Wolf     free_cmdline_args(args, nb_args);
307ed7bda5dSKevin Wolf }
308ed7bda5dSKevin Wolf 
309ed7bda5dSKevin Wolf /*******************************************************************/
310ed7bda5dSKevin Wolf 
311ed7bda5dSKevin Wolf static const char *pch;
312ed7bda5dSKevin Wolf static sigjmp_buf expr_env;
313ed7bda5dSKevin Wolf 
3148905770bSMarc-André Lureau static G_NORETURN G_GNUC_PRINTF(2, 3)
expr_error(Monitor * mon,const char * fmt,...)3158905770bSMarc-André Lureau void expr_error(Monitor *mon, const char *fmt, ...)
316ed7bda5dSKevin Wolf {
317ed7bda5dSKevin Wolf     va_list ap;
318ed7bda5dSKevin Wolf     va_start(ap, fmt);
319ed7bda5dSKevin Wolf     monitor_vprintf(mon, fmt, ap);
320ed7bda5dSKevin Wolf     monitor_printf(mon, "\n");
321ed7bda5dSKevin Wolf     va_end(ap);
322ed7bda5dSKevin Wolf     siglongjmp(expr_env, 1);
323ed7bda5dSKevin Wolf }
324ed7bda5dSKevin Wolf 
next(void)325ed7bda5dSKevin Wolf static void next(void)
326ed7bda5dSKevin Wolf {
327ed7bda5dSKevin Wolf     if (*pch != '\0') {
328ed7bda5dSKevin Wolf         pch++;
329ed7bda5dSKevin Wolf         while (qemu_isspace(*pch)) {
330ed7bda5dSKevin Wolf             pch++;
331ed7bda5dSKevin Wolf         }
332ed7bda5dSKevin Wolf     }
333ed7bda5dSKevin Wolf }
334ed7bda5dSKevin Wolf 
335ed7bda5dSKevin Wolf static int64_t expr_sum(Monitor *mon);
336ed7bda5dSKevin Wolf 
expr_unary(Monitor * mon)337ed7bda5dSKevin Wolf static int64_t expr_unary(Monitor *mon)
338ed7bda5dSKevin Wolf {
339ed7bda5dSKevin Wolf     int64_t n;
340ed7bda5dSKevin Wolf     char *p;
341ed7bda5dSKevin Wolf     int ret;
342ed7bda5dSKevin Wolf 
343ed7bda5dSKevin Wolf     switch (*pch) {
344ed7bda5dSKevin Wolf     case '+':
345ed7bda5dSKevin Wolf         next();
346ed7bda5dSKevin Wolf         n = expr_unary(mon);
347ed7bda5dSKevin Wolf         break;
348ed7bda5dSKevin Wolf     case '-':
349ed7bda5dSKevin Wolf         next();
350ed7bda5dSKevin Wolf         n = -expr_unary(mon);
351ed7bda5dSKevin Wolf         break;
352ed7bda5dSKevin Wolf     case '~':
353ed7bda5dSKevin Wolf         next();
354ed7bda5dSKevin Wolf         n = ~expr_unary(mon);
355ed7bda5dSKevin Wolf         break;
356ed7bda5dSKevin Wolf     case '(':
357ed7bda5dSKevin Wolf         next();
358ed7bda5dSKevin Wolf         n = expr_sum(mon);
359ed7bda5dSKevin Wolf         if (*pch != ')') {
360ed7bda5dSKevin Wolf             expr_error(mon, "')' expected");
361ed7bda5dSKevin Wolf         }
362ed7bda5dSKevin Wolf         next();
363ed7bda5dSKevin Wolf         break;
364ed7bda5dSKevin Wolf     case '\'':
365ed7bda5dSKevin Wolf         pch++;
366ed7bda5dSKevin Wolf         if (*pch == '\0') {
367ed7bda5dSKevin Wolf             expr_error(mon, "character constant expected");
368ed7bda5dSKevin Wolf         }
369ed7bda5dSKevin Wolf         n = *pch;
370ed7bda5dSKevin Wolf         pch++;
371ed7bda5dSKevin Wolf         if (*pch != '\'') {
372ed7bda5dSKevin Wolf             expr_error(mon, "missing terminating \' character");
373ed7bda5dSKevin Wolf         }
374ed7bda5dSKevin Wolf         next();
375ed7bda5dSKevin Wolf         break;
376ed7bda5dSKevin Wolf     case '$':
377ed7bda5dSKevin Wolf         {
378ed7bda5dSKevin Wolf             char buf[128], *q;
379ed7bda5dSKevin Wolf             int64_t reg = 0;
380ed7bda5dSKevin Wolf 
381ed7bda5dSKevin Wolf             pch++;
382ed7bda5dSKevin Wolf             q = buf;
383ed7bda5dSKevin Wolf             while ((*pch >= 'a' && *pch <= 'z') ||
384ed7bda5dSKevin Wolf                    (*pch >= 'A' && *pch <= 'Z') ||
385ed7bda5dSKevin Wolf                    (*pch >= '0' && *pch <= '9') ||
386ed7bda5dSKevin Wolf                    *pch == '_' || *pch == '.') {
387ed7bda5dSKevin Wolf                 if ((q - buf) < sizeof(buf) - 1) {
388ed7bda5dSKevin Wolf                     *q++ = *pch;
389ed7bda5dSKevin Wolf                 }
390ed7bda5dSKevin Wolf                 pch++;
391ed7bda5dSKevin Wolf             }
392ed7bda5dSKevin Wolf             while (qemu_isspace(*pch)) {
393ed7bda5dSKevin Wolf                 pch++;
394ed7bda5dSKevin Wolf             }
395ed7bda5dSKevin Wolf             *q = 0;
3962fc5d01bSKevin Wolf             ret = get_monitor_def(mon, &reg, buf);
397ed7bda5dSKevin Wolf             if (ret < 0) {
398ed7bda5dSKevin Wolf                 expr_error(mon, "unknown register");
399ed7bda5dSKevin Wolf             }
400ed7bda5dSKevin Wolf             n = reg;
401ed7bda5dSKevin Wolf         }
402ed7bda5dSKevin Wolf         break;
403ed7bda5dSKevin Wolf     case '\0':
404ed7bda5dSKevin Wolf         expr_error(mon, "unexpected end of expression");
405ed7bda5dSKevin Wolf         n = 0;
406ed7bda5dSKevin Wolf         break;
407ed7bda5dSKevin Wolf     default:
408ed7bda5dSKevin Wolf         errno = 0;
409ed7bda5dSKevin Wolf         n = strtoull(pch, &p, 0);
410ed7bda5dSKevin Wolf         if (errno == ERANGE) {
411ed7bda5dSKevin Wolf             expr_error(mon, "number too large");
412ed7bda5dSKevin Wolf         }
413ed7bda5dSKevin Wolf         if (pch == p) {
414ed7bda5dSKevin Wolf             expr_error(mon, "invalid char '%c' in expression", *p);
415ed7bda5dSKevin Wolf         }
416ed7bda5dSKevin Wolf         pch = p;
417ed7bda5dSKevin Wolf         while (qemu_isspace(*pch)) {
418ed7bda5dSKevin Wolf             pch++;
419ed7bda5dSKevin Wolf         }
420ed7bda5dSKevin Wolf         break;
421ed7bda5dSKevin Wolf     }
422ed7bda5dSKevin Wolf     return n;
423ed7bda5dSKevin Wolf }
424ed7bda5dSKevin Wolf 
expr_prod(Monitor * mon)425ed7bda5dSKevin Wolf static int64_t expr_prod(Monitor *mon)
426ed7bda5dSKevin Wolf {
427ed7bda5dSKevin Wolf     int64_t val, val2;
428ed7bda5dSKevin Wolf     int op;
429ed7bda5dSKevin Wolf 
430ed7bda5dSKevin Wolf     val = expr_unary(mon);
431ed7bda5dSKevin Wolf     for (;;) {
432ed7bda5dSKevin Wolf         op = *pch;
433ed7bda5dSKevin Wolf         if (op != '*' && op != '/' && op != '%') {
434ed7bda5dSKevin Wolf             break;
435ed7bda5dSKevin Wolf         }
436ed7bda5dSKevin Wolf         next();
437ed7bda5dSKevin Wolf         val2 = expr_unary(mon);
438ed7bda5dSKevin Wolf         switch (op) {
439ed7bda5dSKevin Wolf         default:
440ed7bda5dSKevin Wolf         case '*':
441ed7bda5dSKevin Wolf             val *= val2;
442ed7bda5dSKevin Wolf             break;
443ed7bda5dSKevin Wolf         case '/':
444ed7bda5dSKevin Wolf         case '%':
445ed7bda5dSKevin Wolf             if (val2 == 0) {
446ed7bda5dSKevin Wolf                 expr_error(mon, "division by zero");
447ed7bda5dSKevin Wolf             }
448ed7bda5dSKevin Wolf             if (op == '/') {
449ed7bda5dSKevin Wolf                 val /= val2;
450ed7bda5dSKevin Wolf             } else {
451ed7bda5dSKevin Wolf                 val %= val2;
452ed7bda5dSKevin Wolf             }
453ed7bda5dSKevin Wolf             break;
454ed7bda5dSKevin Wolf         }
455ed7bda5dSKevin Wolf     }
456ed7bda5dSKevin Wolf     return val;
457ed7bda5dSKevin Wolf }
458ed7bda5dSKevin Wolf 
expr_logic(Monitor * mon)459ed7bda5dSKevin Wolf static int64_t expr_logic(Monitor *mon)
460ed7bda5dSKevin Wolf {
461ed7bda5dSKevin Wolf     int64_t val, val2;
462ed7bda5dSKevin Wolf     int op;
463ed7bda5dSKevin Wolf 
464ed7bda5dSKevin Wolf     val = expr_prod(mon);
465ed7bda5dSKevin Wolf     for (;;) {
466ed7bda5dSKevin Wolf         op = *pch;
467ed7bda5dSKevin Wolf         if (op != '&' && op != '|' && op != '^') {
468ed7bda5dSKevin Wolf             break;
469ed7bda5dSKevin Wolf         }
470ed7bda5dSKevin Wolf         next();
471ed7bda5dSKevin Wolf         val2 = expr_prod(mon);
472ed7bda5dSKevin Wolf         switch (op) {
473ed7bda5dSKevin Wolf         default:
474ed7bda5dSKevin Wolf         case '&':
475ed7bda5dSKevin Wolf             val &= val2;
476ed7bda5dSKevin Wolf             break;
477ed7bda5dSKevin Wolf         case '|':
478ed7bda5dSKevin Wolf             val |= val2;
479ed7bda5dSKevin Wolf             break;
480ed7bda5dSKevin Wolf         case '^':
481ed7bda5dSKevin Wolf             val ^= val2;
482ed7bda5dSKevin Wolf             break;
483ed7bda5dSKevin Wolf         }
484ed7bda5dSKevin Wolf     }
485ed7bda5dSKevin Wolf     return val;
486ed7bda5dSKevin Wolf }
487ed7bda5dSKevin Wolf 
expr_sum(Monitor * mon)488ed7bda5dSKevin Wolf static int64_t expr_sum(Monitor *mon)
489ed7bda5dSKevin Wolf {
490ed7bda5dSKevin Wolf     int64_t val, val2;
491ed7bda5dSKevin Wolf     int op;
492ed7bda5dSKevin Wolf 
493ed7bda5dSKevin Wolf     val = expr_logic(mon);
494ed7bda5dSKevin Wolf     for (;;) {
495ed7bda5dSKevin Wolf         op = *pch;
496ed7bda5dSKevin Wolf         if (op != '+' && op != '-') {
497ed7bda5dSKevin Wolf             break;
498ed7bda5dSKevin Wolf         }
499ed7bda5dSKevin Wolf         next();
500ed7bda5dSKevin Wolf         val2 = expr_logic(mon);
501ed7bda5dSKevin Wolf         if (op == '+') {
502ed7bda5dSKevin Wolf             val += val2;
503ed7bda5dSKevin Wolf         } else {
504ed7bda5dSKevin Wolf             val -= val2;
505ed7bda5dSKevin Wolf         }
506ed7bda5dSKevin Wolf     }
507ed7bda5dSKevin Wolf     return val;
508ed7bda5dSKevin Wolf }
509ed7bda5dSKevin Wolf 
get_expr(Monitor * mon,int64_t * pval,const char ** pp)510ed7bda5dSKevin Wolf static int get_expr(Monitor *mon, int64_t *pval, const char **pp)
511ed7bda5dSKevin Wolf {
512ed7bda5dSKevin Wolf     pch = *pp;
513ed7bda5dSKevin Wolf     if (sigsetjmp(expr_env, 0)) {
514ed7bda5dSKevin Wolf         *pp = pch;
515ed7bda5dSKevin Wolf         return -1;
516ed7bda5dSKevin Wolf     }
517ed7bda5dSKevin Wolf     while (qemu_isspace(*pch)) {
518ed7bda5dSKevin Wolf         pch++;
519ed7bda5dSKevin Wolf     }
520ed7bda5dSKevin Wolf     *pval = expr_sum(mon);
521ed7bda5dSKevin Wolf     *pp = pch;
522ed7bda5dSKevin Wolf     return 0;
523ed7bda5dSKevin Wolf }
524ed7bda5dSKevin Wolf 
get_double(Monitor * mon,double * pval,const char ** pp)525ed7bda5dSKevin Wolf static int get_double(Monitor *mon, double *pval, const char **pp)
526ed7bda5dSKevin Wolf {
527ed7bda5dSKevin Wolf     const char *p = *pp;
528ed7bda5dSKevin Wolf     char *tailp;
529ed7bda5dSKevin Wolf     double d;
530ed7bda5dSKevin Wolf 
531ed7bda5dSKevin Wolf     d = strtod(p, &tailp);
532ed7bda5dSKevin Wolf     if (tailp == p) {
533ed7bda5dSKevin Wolf         monitor_printf(mon, "Number expected\n");
534ed7bda5dSKevin Wolf         return -1;
535ed7bda5dSKevin Wolf     }
536ed7bda5dSKevin Wolf     if (d != d || d - d != 0) {
537ed7bda5dSKevin Wolf         /* NaN or infinity */
538ed7bda5dSKevin Wolf         monitor_printf(mon, "Bad number\n");
539ed7bda5dSKevin Wolf         return -1;
540ed7bda5dSKevin Wolf     }
541ed7bda5dSKevin Wolf     *pval = d;
542ed7bda5dSKevin Wolf     *pp = tailp;
543ed7bda5dSKevin Wolf     return 0;
544ed7bda5dSKevin Wolf }
545ed7bda5dSKevin Wolf 
546ed7bda5dSKevin Wolf /*
547ed7bda5dSKevin Wolf  * Store the command-name in cmdname, and return a pointer to
548ed7bda5dSKevin Wolf  * the remaining of the command string.
549ed7bda5dSKevin Wolf  */
get_command_name(const char * cmdline,char * cmdname,size_t nlen)550ed7bda5dSKevin Wolf static const char *get_command_name(const char *cmdline,
551ed7bda5dSKevin Wolf                                     char *cmdname, size_t nlen)
552ed7bda5dSKevin Wolf {
553ed7bda5dSKevin Wolf     size_t len;
554ed7bda5dSKevin Wolf     const char *p, *pstart;
555ed7bda5dSKevin Wolf 
556ed7bda5dSKevin Wolf     p = cmdline;
557ed7bda5dSKevin Wolf     while (qemu_isspace(*p)) {
558ed7bda5dSKevin Wolf         p++;
559ed7bda5dSKevin Wolf     }
560ed7bda5dSKevin Wolf     if (*p == '\0') {
561ed7bda5dSKevin Wolf         return NULL;
562ed7bda5dSKevin Wolf     }
563ed7bda5dSKevin Wolf     pstart = p;
564ed7bda5dSKevin Wolf     while (*p != '\0' && *p != '/' && !qemu_isspace(*p)) {
565ed7bda5dSKevin Wolf         p++;
566ed7bda5dSKevin Wolf     }
567ed7bda5dSKevin Wolf     len = p - pstart;
568ed7bda5dSKevin Wolf     if (len > nlen - 1) {
569ed7bda5dSKevin Wolf         len = nlen - 1;
570ed7bda5dSKevin Wolf     }
571ed7bda5dSKevin Wolf     memcpy(cmdname, pstart, len);
572ed7bda5dSKevin Wolf     cmdname[len] = '\0';
573ed7bda5dSKevin Wolf     return p;
574ed7bda5dSKevin Wolf }
575ed7bda5dSKevin Wolf 
576ed7bda5dSKevin Wolf /**
577ed7bda5dSKevin Wolf  * Read key of 'type' into 'key' and return the current
578ed7bda5dSKevin Wolf  * 'type' pointer.
579ed7bda5dSKevin Wolf  */
key_get_info(const char * type,char ** key)580ed7bda5dSKevin Wolf static char *key_get_info(const char *type, char **key)
581ed7bda5dSKevin Wolf {
582ed7bda5dSKevin Wolf     size_t len;
583ed7bda5dSKevin Wolf     char *p, *str;
584ed7bda5dSKevin Wolf 
585ed7bda5dSKevin Wolf     if (*type == ',') {
586ed7bda5dSKevin Wolf         type++;
587ed7bda5dSKevin Wolf     }
588ed7bda5dSKevin Wolf 
589ed7bda5dSKevin Wolf     p = strchr(type, ':');
590ed7bda5dSKevin Wolf     if (!p) {
591ed7bda5dSKevin Wolf         *key = NULL;
592ed7bda5dSKevin Wolf         return NULL;
593ed7bda5dSKevin Wolf     }
594ed7bda5dSKevin Wolf     len = p - type;
595ed7bda5dSKevin Wolf 
596ed7bda5dSKevin Wolf     str = g_malloc(len + 1);
597ed7bda5dSKevin Wolf     memcpy(str, type, len);
598ed7bda5dSKevin Wolf     str[len] = '\0';
599ed7bda5dSKevin Wolf 
600ed7bda5dSKevin Wolf     *key = str;
601ed7bda5dSKevin Wolf     return ++p;
602ed7bda5dSKevin Wolf }
603ed7bda5dSKevin Wolf 
604ed7bda5dSKevin Wolf static int default_fmt_format = 'x';
605ed7bda5dSKevin Wolf static int default_fmt_size = 4;
606ed7bda5dSKevin Wolf 
is_valid_option(const char * c,const char * typestr)607ed7bda5dSKevin Wolf static int is_valid_option(const char *c, const char *typestr)
608ed7bda5dSKevin Wolf {
609ed7bda5dSKevin Wolf     char option[3];
610ed7bda5dSKevin Wolf 
611ed7bda5dSKevin Wolf     option[0] = '-';
612ed7bda5dSKevin Wolf     option[1] = *c;
613ed7bda5dSKevin Wolf     option[2] = '\0';
614ed7bda5dSKevin Wolf 
615ed7bda5dSKevin Wolf     typestr = strstr(typestr, option);
616ed7bda5dSKevin Wolf     return (typestr != NULL);
617ed7bda5dSKevin Wolf }
618ed7bda5dSKevin Wolf 
search_dispatch_table(const HMPCommand * disp_table,const char * cmdname)619ed7bda5dSKevin Wolf static const HMPCommand *search_dispatch_table(const HMPCommand *disp_table,
620ed7bda5dSKevin Wolf                                                const char *cmdname)
621ed7bda5dSKevin Wolf {
622ed7bda5dSKevin Wolf     const HMPCommand *cmd;
623ed7bda5dSKevin Wolf 
624ed7bda5dSKevin Wolf     for (cmd = disp_table; cmd->name != NULL; cmd++) {
625ed7bda5dSKevin Wolf         if (hmp_compare_cmd(cmdname, cmd->name)) {
626ed7bda5dSKevin Wolf             return cmd;
627ed7bda5dSKevin Wolf         }
628ed7bda5dSKevin Wolf     }
629ed7bda5dSKevin Wolf 
630ed7bda5dSKevin Wolf     return NULL;
631ed7bda5dSKevin Wolf }
632ed7bda5dSKevin Wolf 
633ed7bda5dSKevin Wolf /*
634ed7bda5dSKevin Wolf  * Parse command name from @cmdp according to command table @table.
635ed7bda5dSKevin Wolf  * If blank, return NULL.
636ed7bda5dSKevin Wolf  * Else, if no valid command can be found, report to @mon, and return
637ed7bda5dSKevin Wolf  * NULL.
638ed7bda5dSKevin Wolf  * Else, change @cmdp to point right behind the name, and return its
639ed7bda5dSKevin Wolf  * command table entry.
640ed7bda5dSKevin Wolf  * Do not assume the return value points into @table!  It doesn't when
641ed7bda5dSKevin Wolf  * the command is found in a sub-command table.
642ed7bda5dSKevin Wolf  */
monitor_parse_command(MonitorHMP * hmp_mon,const char * cmdp_start,const char ** cmdp,HMPCommand * table)643ed7bda5dSKevin Wolf static const HMPCommand *monitor_parse_command(MonitorHMP *hmp_mon,
644ed7bda5dSKevin Wolf                                                const char *cmdp_start,
645ed7bda5dSKevin Wolf                                                const char **cmdp,
646ed7bda5dSKevin Wolf                                                HMPCommand *table)
647ed7bda5dSKevin Wolf {
648ed7bda5dSKevin Wolf     Monitor *mon = &hmp_mon->common;
649ed7bda5dSKevin Wolf     const char *p;
650ed7bda5dSKevin Wolf     const HMPCommand *cmd;
651ed7bda5dSKevin Wolf     char cmdname[256];
652ed7bda5dSKevin Wolf 
653ed7bda5dSKevin Wolf     /* extract the command name */
654ed7bda5dSKevin Wolf     p = get_command_name(*cmdp, cmdname, sizeof(cmdname));
655ed7bda5dSKevin Wolf     if (!p) {
656ed7bda5dSKevin Wolf         return NULL;
657ed7bda5dSKevin Wolf     }
658ed7bda5dSKevin Wolf 
659ed7bda5dSKevin Wolf     cmd = search_dispatch_table(table, cmdname);
660ed7bda5dSKevin Wolf     if (!cmd) {
661ed7bda5dSKevin Wolf         monitor_printf(mon, "unknown command: '%.*s'\n",
662ed7bda5dSKevin Wolf                        (int)(p - cmdp_start), cmdp_start);
663ed7bda5dSKevin Wolf         return NULL;
664ed7bda5dSKevin Wolf     }
6654cd29274SPaolo Bonzini     if (!cmd_available(cmd)) {
666164dafd1SPaolo Bonzini         monitor_printf(mon, "Command '%.*s' not available "
667164dafd1SPaolo Bonzini                             "until machine initialization has completed.\n",
668ed7bda5dSKevin Wolf                        (int)(p - cmdp_start), cmdp_start);
669ed7bda5dSKevin Wolf         return NULL;
670ed7bda5dSKevin Wolf     }
671ed7bda5dSKevin Wolf 
672ed7bda5dSKevin Wolf     /* filter out following useless space */
673ed7bda5dSKevin Wolf     while (qemu_isspace(*p)) {
674ed7bda5dSKevin Wolf         p++;
675ed7bda5dSKevin Wolf     }
676ed7bda5dSKevin Wolf 
677ed7bda5dSKevin Wolf     *cmdp = p;
678ed7bda5dSKevin Wolf     /* search sub command */
679ed7bda5dSKevin Wolf     if (cmd->sub_table != NULL && *p != '\0') {
680ed7bda5dSKevin Wolf         return monitor_parse_command(hmp_mon, cmdp_start, cmdp, cmd->sub_table);
681ed7bda5dSKevin Wolf     }
682ed7bda5dSKevin Wolf 
683ed7bda5dSKevin Wolf     return cmd;
684ed7bda5dSKevin Wolf }
685ed7bda5dSKevin Wolf 
686ed7bda5dSKevin Wolf /*
687ed7bda5dSKevin Wolf  * Parse arguments for @cmd.
688ed7bda5dSKevin Wolf  * If it can't be parsed, report to @mon, and return NULL.
689ed7bda5dSKevin Wolf  * Else, insert command arguments into a QDict, and return it.
690ed7bda5dSKevin Wolf  * Note: On success, caller has to free the QDict structure.
691ed7bda5dSKevin Wolf  */
monitor_parse_arguments(Monitor * mon,const char ** endp,const HMPCommand * cmd)692ed7bda5dSKevin Wolf static QDict *monitor_parse_arguments(Monitor *mon,
693ed7bda5dSKevin Wolf                                       const char **endp,
694ed7bda5dSKevin Wolf                                       const HMPCommand *cmd)
695ed7bda5dSKevin Wolf {
696ed7bda5dSKevin Wolf     const char *typestr;
697ed7bda5dSKevin Wolf     char *key;
698ed7bda5dSKevin Wolf     int c;
699ed7bda5dSKevin Wolf     const char *p = *endp;
700ed7bda5dSKevin Wolf     char buf[1024];
701ed7bda5dSKevin Wolf     QDict *qdict = qdict_new();
702ed7bda5dSKevin Wolf 
703ed7bda5dSKevin Wolf     /* parse the parameters */
704ed7bda5dSKevin Wolf     typestr = cmd->args_type;
705ed7bda5dSKevin Wolf     for (;;) {
706ed7bda5dSKevin Wolf         typestr = key_get_info(typestr, &key);
707ed7bda5dSKevin Wolf         if (!typestr) {
708ed7bda5dSKevin Wolf             break;
709ed7bda5dSKevin Wolf         }
710ed7bda5dSKevin Wolf         c = *typestr;
711ed7bda5dSKevin Wolf         typestr++;
712ed7bda5dSKevin Wolf         switch (c) {
713ed7bda5dSKevin Wolf         case 'F':
714ed7bda5dSKevin Wolf         case 'B':
715ed7bda5dSKevin Wolf         case 's':
716ed7bda5dSKevin Wolf             {
717ed7bda5dSKevin Wolf                 int ret;
718ed7bda5dSKevin Wolf 
719ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
720ed7bda5dSKevin Wolf                     p++;
721ed7bda5dSKevin Wolf                 }
722ed7bda5dSKevin Wolf                 if (*typestr == '?') {
723ed7bda5dSKevin Wolf                     typestr++;
724ed7bda5dSKevin Wolf                     if (*p == '\0') {
725ed7bda5dSKevin Wolf                         /* no optional string: NULL argument */
726ed7bda5dSKevin Wolf                         break;
727ed7bda5dSKevin Wolf                     }
728ed7bda5dSKevin Wolf                 }
729ed7bda5dSKevin Wolf                 ret = get_str(buf, sizeof(buf), &p);
730ed7bda5dSKevin Wolf                 if (ret < 0) {
731ed7bda5dSKevin Wolf                     switch (c) {
732ed7bda5dSKevin Wolf                     case 'F':
733ed7bda5dSKevin Wolf                         monitor_printf(mon, "%s: filename expected\n",
734ed7bda5dSKevin Wolf                                        cmd->name);
735ed7bda5dSKevin Wolf                         break;
736ed7bda5dSKevin Wolf                     case 'B':
737ed7bda5dSKevin Wolf                         monitor_printf(mon, "%s: block device name expected\n",
738ed7bda5dSKevin Wolf                                        cmd->name);
739ed7bda5dSKevin Wolf                         break;
740ed7bda5dSKevin Wolf                     default:
741ed7bda5dSKevin Wolf                         monitor_printf(mon, "%s: string expected\n", cmd->name);
742ed7bda5dSKevin Wolf                         break;
743ed7bda5dSKevin Wolf                     }
744ed7bda5dSKevin Wolf                     goto fail;
745ed7bda5dSKevin Wolf                 }
746ed7bda5dSKevin Wolf                 qdict_put_str(qdict, key, buf);
747ed7bda5dSKevin Wolf             }
748ed7bda5dSKevin Wolf             break;
749ed7bda5dSKevin Wolf         case 'O':
750ed7bda5dSKevin Wolf             {
751ed7bda5dSKevin Wolf                 QemuOptsList *opts_list;
752ed7bda5dSKevin Wolf                 QemuOpts *opts;
753ed7bda5dSKevin Wolf 
754ed7bda5dSKevin Wolf                 opts_list = qemu_find_opts(key);
755ed7bda5dSKevin Wolf                 if (!opts_list || opts_list->desc->name) {
756ed7bda5dSKevin Wolf                     goto bad_type;
757ed7bda5dSKevin Wolf                 }
758ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
759ed7bda5dSKevin Wolf                     p++;
760ed7bda5dSKevin Wolf                 }
761ed7bda5dSKevin Wolf                 if (!*p) {
762ed7bda5dSKevin Wolf                     break;
763ed7bda5dSKevin Wolf                 }
764ed7bda5dSKevin Wolf                 if (get_str(buf, sizeof(buf), &p) < 0) {
765ed7bda5dSKevin Wolf                     goto fail;
766ed7bda5dSKevin Wolf                 }
767ed7bda5dSKevin Wolf                 opts = qemu_opts_parse_noisily(opts_list, buf, true);
768ed7bda5dSKevin Wolf                 if (!opts) {
769ed7bda5dSKevin Wolf                     goto fail;
770ed7bda5dSKevin Wolf                 }
771ed7bda5dSKevin Wolf                 qemu_opts_to_qdict(opts, qdict);
772ed7bda5dSKevin Wolf                 qemu_opts_del(opts);
773ed7bda5dSKevin Wolf             }
774ed7bda5dSKevin Wolf             break;
775ed7bda5dSKevin Wolf         case '/':
776ed7bda5dSKevin Wolf             {
777ed7bda5dSKevin Wolf                 int count, format, size;
778ed7bda5dSKevin Wolf 
779ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
780ed7bda5dSKevin Wolf                     p++;
781ed7bda5dSKevin Wolf                 }
782ed7bda5dSKevin Wolf                 if (*p == '/') {
783ed7bda5dSKevin Wolf                     /* format found */
784ed7bda5dSKevin Wolf                     p++;
785ed7bda5dSKevin Wolf                     count = 1;
786ed7bda5dSKevin Wolf                     if (qemu_isdigit(*p)) {
787ed7bda5dSKevin Wolf                         count = 0;
788ed7bda5dSKevin Wolf                         while (qemu_isdigit(*p)) {
789ed7bda5dSKevin Wolf                             count = count * 10 + (*p - '0');
790ed7bda5dSKevin Wolf                             p++;
791ed7bda5dSKevin Wolf                         }
792ed7bda5dSKevin Wolf                     }
793ed7bda5dSKevin Wolf                     size = -1;
794ed7bda5dSKevin Wolf                     format = -1;
795ed7bda5dSKevin Wolf                     for (;;) {
796ed7bda5dSKevin Wolf                         switch (*p) {
797ed7bda5dSKevin Wolf                         case 'o':
798ed7bda5dSKevin Wolf                         case 'd':
799ed7bda5dSKevin Wolf                         case 'u':
800ed7bda5dSKevin Wolf                         case 'x':
801ed7bda5dSKevin Wolf                         case 'i':
802ed7bda5dSKevin Wolf                         case 'c':
803ed7bda5dSKevin Wolf                             format = *p++;
804ed7bda5dSKevin Wolf                             break;
805ed7bda5dSKevin Wolf                         case 'b':
806ed7bda5dSKevin Wolf                             size = 1;
807ed7bda5dSKevin Wolf                             p++;
808ed7bda5dSKevin Wolf                             break;
809ed7bda5dSKevin Wolf                         case 'h':
810ed7bda5dSKevin Wolf                             size = 2;
811ed7bda5dSKevin Wolf                             p++;
812ed7bda5dSKevin Wolf                             break;
813ed7bda5dSKevin Wolf                         case 'w':
814ed7bda5dSKevin Wolf                             size = 4;
815ed7bda5dSKevin Wolf                             p++;
816ed7bda5dSKevin Wolf                             break;
817ed7bda5dSKevin Wolf                         case 'g':
818ed7bda5dSKevin Wolf                         case 'L':
819ed7bda5dSKevin Wolf                             size = 8;
820ed7bda5dSKevin Wolf                             p++;
821ed7bda5dSKevin Wolf                             break;
822ed7bda5dSKevin Wolf                         default:
823ed7bda5dSKevin Wolf                             goto next;
824ed7bda5dSKevin Wolf                         }
825ed7bda5dSKevin Wolf                     }
826ed7bda5dSKevin Wolf                 next:
827ed7bda5dSKevin Wolf                     if (*p != '\0' && !qemu_isspace(*p)) {
828ed7bda5dSKevin Wolf                         monitor_printf(mon, "invalid char in format: '%c'\n",
829ed7bda5dSKevin Wolf                                        *p);
830ed7bda5dSKevin Wolf                         goto fail;
831ed7bda5dSKevin Wolf                     }
832ed7bda5dSKevin Wolf                     if (format < 0) {
833ed7bda5dSKevin Wolf                         format = default_fmt_format;
834ed7bda5dSKevin Wolf                     }
835ed7bda5dSKevin Wolf                     if (format != 'i') {
836ed7bda5dSKevin Wolf                         /* for 'i', not specifying a size gives -1 as size */
837ed7bda5dSKevin Wolf                         if (size < 0) {
838ed7bda5dSKevin Wolf                             size = default_fmt_size;
839ed7bda5dSKevin Wolf                         }
840ed7bda5dSKevin Wolf                         default_fmt_size = size;
841ed7bda5dSKevin Wolf                     }
842ed7bda5dSKevin Wolf                     default_fmt_format = format;
843ed7bda5dSKevin Wolf                 } else {
844ed7bda5dSKevin Wolf                     count = 1;
845ed7bda5dSKevin Wolf                     format = default_fmt_format;
846ed7bda5dSKevin Wolf                     if (format != 'i') {
847ed7bda5dSKevin Wolf                         size = default_fmt_size;
848ed7bda5dSKevin Wolf                     } else {
849ed7bda5dSKevin Wolf                         size = -1;
850ed7bda5dSKevin Wolf                     }
851ed7bda5dSKevin Wolf                 }
852ed7bda5dSKevin Wolf                 qdict_put_int(qdict, "count", count);
853ed7bda5dSKevin Wolf                 qdict_put_int(qdict, "format", format);
854ed7bda5dSKevin Wolf                 qdict_put_int(qdict, "size", size);
855ed7bda5dSKevin Wolf             }
856ed7bda5dSKevin Wolf             break;
857ed7bda5dSKevin Wolf         case 'i':
858ed7bda5dSKevin Wolf         case 'l':
859ed7bda5dSKevin Wolf         case 'M':
860ed7bda5dSKevin Wolf             {
861ed7bda5dSKevin Wolf                 int64_t val;
862ed7bda5dSKevin Wolf 
863ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
864ed7bda5dSKevin Wolf                     p++;
865ed7bda5dSKevin Wolf                 }
866ed7bda5dSKevin Wolf                 if (*typestr == '?' || *typestr == '.') {
867ed7bda5dSKevin Wolf                     if (*typestr == '?') {
868ed7bda5dSKevin Wolf                         if (*p == '\0') {
869ed7bda5dSKevin Wolf                             typestr++;
870ed7bda5dSKevin Wolf                             break;
871ed7bda5dSKevin Wolf                         }
872ed7bda5dSKevin Wolf                     } else {
873ed7bda5dSKevin Wolf                         if (*p == '.') {
874ed7bda5dSKevin Wolf                             p++;
875ed7bda5dSKevin Wolf                             while (qemu_isspace(*p)) {
876ed7bda5dSKevin Wolf                                 p++;
877ed7bda5dSKevin Wolf                             }
878ed7bda5dSKevin Wolf                         } else {
879ed7bda5dSKevin Wolf                             typestr++;
880ed7bda5dSKevin Wolf                             break;
881ed7bda5dSKevin Wolf                         }
882ed7bda5dSKevin Wolf                     }
883ed7bda5dSKevin Wolf                     typestr++;
884ed7bda5dSKevin Wolf                 }
885ed7bda5dSKevin Wolf                 if (get_expr(mon, &val, &p)) {
886ed7bda5dSKevin Wolf                     goto fail;
887ed7bda5dSKevin Wolf                 }
888ed7bda5dSKevin Wolf                 /* Check if 'i' is greater than 32-bit */
889ed7bda5dSKevin Wolf                 if ((c == 'i') && ((val >> 32) & 0xffffffff)) {
890ed7bda5dSKevin Wolf                     monitor_printf(mon, "\'%s\' has failed: ", cmd->name);
891ed7bda5dSKevin Wolf                     monitor_printf(mon, "integer is for 32-bit values\n");
892ed7bda5dSKevin Wolf                     goto fail;
893ed7bda5dSKevin Wolf                 } else if (c == 'M') {
894ed7bda5dSKevin Wolf                     if (val < 0) {
895ed7bda5dSKevin Wolf                         monitor_printf(mon, "enter a positive value\n");
896ed7bda5dSKevin Wolf                         goto fail;
897ed7bda5dSKevin Wolf                     }
898ed7bda5dSKevin Wolf                     val *= MiB;
899ed7bda5dSKevin Wolf                 }
900ed7bda5dSKevin Wolf                 qdict_put_int(qdict, key, val);
901ed7bda5dSKevin Wolf             }
902ed7bda5dSKevin Wolf             break;
903ed7bda5dSKevin Wolf         case 'o':
904ed7bda5dSKevin Wolf             {
905ed7bda5dSKevin Wolf                 int ret;
906ed7bda5dSKevin Wolf                 uint64_t val;
907ed7bda5dSKevin Wolf                 const char *end;
908ed7bda5dSKevin Wolf 
909ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
910ed7bda5dSKevin Wolf                     p++;
911ed7bda5dSKevin Wolf                 }
912ed7bda5dSKevin Wolf                 if (*typestr == '?') {
913ed7bda5dSKevin Wolf                     typestr++;
914ed7bda5dSKevin Wolf                     if (*p == '\0') {
915ed7bda5dSKevin Wolf                         break;
916ed7bda5dSKevin Wolf                     }
917ed7bda5dSKevin Wolf                 }
918ed7bda5dSKevin Wolf                 ret = qemu_strtosz_MiB(p, &end, &val);
919ed7bda5dSKevin Wolf                 if (ret < 0 || val > INT64_MAX) {
920ed7bda5dSKevin Wolf                     monitor_printf(mon, "invalid size\n");
921ed7bda5dSKevin Wolf                     goto fail;
922ed7bda5dSKevin Wolf                 }
923ed7bda5dSKevin Wolf                 qdict_put_int(qdict, key, val);
924ed7bda5dSKevin Wolf                 p = end;
925ed7bda5dSKevin Wolf             }
926ed7bda5dSKevin Wolf             break;
927ed7bda5dSKevin Wolf         case 'T':
928ed7bda5dSKevin Wolf             {
929ed7bda5dSKevin Wolf                 double val;
930ed7bda5dSKevin Wolf 
931ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
932ed7bda5dSKevin Wolf                     p++;
933ed7bda5dSKevin Wolf                 }
934ed7bda5dSKevin Wolf                 if (*typestr == '?') {
935ed7bda5dSKevin Wolf                     typestr++;
936ed7bda5dSKevin Wolf                     if (*p == '\0') {
937ed7bda5dSKevin Wolf                         break;
938ed7bda5dSKevin Wolf                     }
939ed7bda5dSKevin Wolf                 }
940ed7bda5dSKevin Wolf                 if (get_double(mon, &val, &p) < 0) {
941ed7bda5dSKevin Wolf                     goto fail;
942ed7bda5dSKevin Wolf                 }
943ed7bda5dSKevin Wolf                 if (p[0] && p[1] == 's') {
944ed7bda5dSKevin Wolf                     switch (*p) {
945ed7bda5dSKevin Wolf                     case 'm':
946ed7bda5dSKevin Wolf                         val /= 1e3; p += 2; break;
947ed7bda5dSKevin Wolf                     case 'u':
948ed7bda5dSKevin Wolf                         val /= 1e6; p += 2; break;
949ed7bda5dSKevin Wolf                     case 'n':
950ed7bda5dSKevin Wolf                         val /= 1e9; p += 2; break;
951ed7bda5dSKevin Wolf                     }
952ed7bda5dSKevin Wolf                 }
953ed7bda5dSKevin Wolf                 if (*p && !qemu_isspace(*p)) {
954ed7bda5dSKevin Wolf                     monitor_printf(mon, "Unknown unit suffix\n");
955ed7bda5dSKevin Wolf                     goto fail;
956ed7bda5dSKevin Wolf                 }
957ed7bda5dSKevin Wolf                 qdict_put(qdict, key, qnum_from_double(val));
958ed7bda5dSKevin Wolf             }
959ed7bda5dSKevin Wolf             break;
960ed7bda5dSKevin Wolf         case 'b':
961ed7bda5dSKevin Wolf             {
962ed7bda5dSKevin Wolf                 const char *beg;
963ed7bda5dSKevin Wolf                 bool val;
964ed7bda5dSKevin Wolf 
965ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
966ed7bda5dSKevin Wolf                     p++;
967ed7bda5dSKevin Wolf                 }
968ed7bda5dSKevin Wolf                 beg = p;
969ed7bda5dSKevin Wolf                 while (qemu_isgraph(*p)) {
970ed7bda5dSKevin Wolf                     p++;
971ed7bda5dSKevin Wolf                 }
972ed7bda5dSKevin Wolf                 if (p - beg == 2 && !memcmp(beg, "on", p - beg)) {
973ed7bda5dSKevin Wolf                     val = true;
974ed7bda5dSKevin Wolf                 } else if (p - beg == 3 && !memcmp(beg, "off", p - beg)) {
975ed7bda5dSKevin Wolf                     val = false;
976ed7bda5dSKevin Wolf                 } else {
977ed7bda5dSKevin Wolf                     monitor_printf(mon, "Expected 'on' or 'off'\n");
978ed7bda5dSKevin Wolf                     goto fail;
979ed7bda5dSKevin Wolf                 }
980ed7bda5dSKevin Wolf                 qdict_put_bool(qdict, key, val);
981ed7bda5dSKevin Wolf             }
982ed7bda5dSKevin Wolf             break;
983ed7bda5dSKevin Wolf         case '-':
984ed7bda5dSKevin Wolf             {
985ed7bda5dSKevin Wolf                 const char *tmp = p;
986ed7bda5dSKevin Wolf                 int skip_key = 0;
98726fcd766SStefan Reiter                 int ret;
988ed7bda5dSKevin Wolf                 /* option */
989ed7bda5dSKevin Wolf 
990ed7bda5dSKevin Wolf                 c = *typestr++;
991ed7bda5dSKevin Wolf                 if (c == '\0') {
992ed7bda5dSKevin Wolf                     goto bad_type;
993ed7bda5dSKevin Wolf                 }
994ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
995ed7bda5dSKevin Wolf                     p++;
996ed7bda5dSKevin Wolf                 }
997ed7bda5dSKevin Wolf                 if (*p == '-') {
998ed7bda5dSKevin Wolf                     p++;
999ed7bda5dSKevin Wolf                     if (c != *p) {
1000ed7bda5dSKevin Wolf                         if (!is_valid_option(p, typestr)) {
1001ed7bda5dSKevin Wolf                             monitor_printf(mon, "%s: unsupported option -%c\n",
1002ed7bda5dSKevin Wolf                                            cmd->name, *p);
1003ed7bda5dSKevin Wolf                             goto fail;
1004ed7bda5dSKevin Wolf                         } else {
1005ed7bda5dSKevin Wolf                             skip_key = 1;
1006ed7bda5dSKevin Wolf                         }
1007ed7bda5dSKevin Wolf                     }
1008ed7bda5dSKevin Wolf                     if (skip_key) {
1009ed7bda5dSKevin Wolf                         p = tmp;
101026fcd766SStefan Reiter                     } else if (*typestr == 's') {
101126fcd766SStefan Reiter                         /* has option with string value */
101226fcd766SStefan Reiter                         typestr++;
101326fcd766SStefan Reiter                         tmp = p++;
101426fcd766SStefan Reiter                         while (qemu_isspace(*p)) {
101526fcd766SStefan Reiter                             p++;
101626fcd766SStefan Reiter                         }
101726fcd766SStefan Reiter                         ret = get_str(buf, sizeof(buf), &p);
101826fcd766SStefan Reiter                         if (ret < 0) {
101926fcd766SStefan Reiter                             monitor_printf(mon, "%s: value expected for -%c\n",
102026fcd766SStefan Reiter                                            cmd->name, *tmp);
102126fcd766SStefan Reiter                             goto fail;
102226fcd766SStefan Reiter                         }
102326fcd766SStefan Reiter                         qdict_put_str(qdict, key, buf);
1024ed7bda5dSKevin Wolf                     } else {
102526fcd766SStefan Reiter                         /* has boolean option */
1026ed7bda5dSKevin Wolf                         p++;
1027ed7bda5dSKevin Wolf                         qdict_put_bool(qdict, key, true);
1028ed7bda5dSKevin Wolf                     }
102926fcd766SStefan Reiter                 } else if (*typestr == 's') {
103026fcd766SStefan Reiter                     typestr++;
1031ed7bda5dSKevin Wolf                 }
1032ed7bda5dSKevin Wolf             }
1033ed7bda5dSKevin Wolf             break;
1034ed7bda5dSKevin Wolf         case 'S':
1035ed7bda5dSKevin Wolf             {
1036ed7bda5dSKevin Wolf                 /* package all remaining string */
1037ed7bda5dSKevin Wolf                 int len;
1038ed7bda5dSKevin Wolf 
1039ed7bda5dSKevin Wolf                 while (qemu_isspace(*p)) {
1040ed7bda5dSKevin Wolf                     p++;
1041ed7bda5dSKevin Wolf                 }
1042ed7bda5dSKevin Wolf                 if (*typestr == '?') {
1043ed7bda5dSKevin Wolf                     typestr++;
1044ed7bda5dSKevin Wolf                     if (*p == '\0') {
1045ed7bda5dSKevin Wolf                         /* no remaining string: NULL argument */
1046ed7bda5dSKevin Wolf                         break;
1047ed7bda5dSKevin Wolf                     }
1048ed7bda5dSKevin Wolf                 }
1049ed7bda5dSKevin Wolf                 len = strlen(p);
1050ed7bda5dSKevin Wolf                 if (len <= 0) {
1051ed7bda5dSKevin Wolf                     monitor_printf(mon, "%s: string expected\n",
1052ed7bda5dSKevin Wolf                                    cmd->name);
1053ed7bda5dSKevin Wolf                     goto fail;
1054ed7bda5dSKevin Wolf                 }
1055ed7bda5dSKevin Wolf                 qdict_put_str(qdict, key, p);
1056ed7bda5dSKevin Wolf                 p += len;
1057ed7bda5dSKevin Wolf             }
1058ed7bda5dSKevin Wolf             break;
1059ed7bda5dSKevin Wolf         default:
1060ed7bda5dSKevin Wolf         bad_type:
1061ed7bda5dSKevin Wolf             monitor_printf(mon, "%s: unknown type '%c'\n", cmd->name, c);
1062ed7bda5dSKevin Wolf             goto fail;
1063ed7bda5dSKevin Wolf         }
1064ed7bda5dSKevin Wolf         g_free(key);
1065ed7bda5dSKevin Wolf         key = NULL;
1066ed7bda5dSKevin Wolf     }
1067ed7bda5dSKevin Wolf     /* check that all arguments were parsed */
1068ed7bda5dSKevin Wolf     while (qemu_isspace(*p)) {
1069ed7bda5dSKevin Wolf         p++;
1070ed7bda5dSKevin Wolf     }
1071ed7bda5dSKevin Wolf     if (*p != '\0') {
1072ed7bda5dSKevin Wolf         monitor_printf(mon, "%s: extraneous characters at the end of line\n",
1073ed7bda5dSKevin Wolf                        cmd->name);
1074ed7bda5dSKevin Wolf         goto fail;
1075ed7bda5dSKevin Wolf     }
1076ed7bda5dSKevin Wolf 
1077ed7bda5dSKevin Wolf     return qdict;
1078ed7bda5dSKevin Wolf 
1079ed7bda5dSKevin Wolf fail:
1080ed7bda5dSKevin Wolf     qobject_unref(qdict);
1081ed7bda5dSKevin Wolf     g_free(key);
1082ed7bda5dSKevin Wolf     return NULL;
1083ed7bda5dSKevin Wolf }
1084ed7bda5dSKevin Wolf 
hmp_info_human_readable_text(Monitor * mon,HumanReadableText * (* handler)(Error **))1085f9429c67SDaniel P. Berrangé static void hmp_info_human_readable_text(Monitor *mon,
1086f9429c67SDaniel P. Berrangé                                          HumanReadableText *(*handler)(Error **))
1087f9429c67SDaniel P. Berrangé {
1088f9429c67SDaniel P. Berrangé     Error *err = NULL;
1089f9429c67SDaniel P. Berrangé     g_autoptr(HumanReadableText) info = handler(&err);
1090f9429c67SDaniel P. Berrangé 
1091f9429c67SDaniel P. Berrangé     if (hmp_handle_error(mon, err)) {
1092f9429c67SDaniel P. Berrangé         return;
1093f9429c67SDaniel P. Berrangé     }
1094f9429c67SDaniel P. Berrangé 
1095bf0c50d4SAlex Bennée     monitor_puts(mon, info->human_readable_text);
1096f9429c67SDaniel P. Berrangé }
1097f9429c67SDaniel P. Berrangé 
handle_hmp_command_exec(Monitor * mon,const HMPCommand * cmd,QDict * qdict)1098f9429c67SDaniel P. Berrangé static void handle_hmp_command_exec(Monitor *mon,
1099f9429c67SDaniel P. Berrangé                                     const HMPCommand *cmd,
1100f9429c67SDaniel P. Berrangé                                     QDict *qdict)
1101f9429c67SDaniel P. Berrangé {
1102f9429c67SDaniel P. Berrangé     if (cmd->cmd_info_hrt) {
1103f9429c67SDaniel P. Berrangé         hmp_info_human_readable_text(mon,
1104f9429c67SDaniel P. Berrangé                                      cmd->cmd_info_hrt);
1105f9429c67SDaniel P. Berrangé     } else {
1106f9429c67SDaniel P. Berrangé         cmd->cmd(mon, qdict);
1107f9429c67SDaniel P. Berrangé     }
1108f9429c67SDaniel P. Berrangé }
1109f9429c67SDaniel P. Berrangé 
1110bb4b9eadSKevin Wolf typedef struct HandleHmpCommandCo {
1111bb4b9eadSKevin Wolf     Monitor *mon;
1112bb4b9eadSKevin Wolf     const HMPCommand *cmd;
1113bb4b9eadSKevin Wolf     QDict *qdict;
1114bb4b9eadSKevin Wolf     bool done;
1115bb4b9eadSKevin Wolf } HandleHmpCommandCo;
1116bb4b9eadSKevin Wolf 
handle_hmp_command_co(void * opaque)1117bb4b9eadSKevin Wolf static void handle_hmp_command_co(void *opaque)
1118bb4b9eadSKevin Wolf {
1119bb4b9eadSKevin Wolf     HandleHmpCommandCo *data = opaque;
1120f9429c67SDaniel P. Berrangé     handle_hmp_command_exec(data->mon, data->cmd, data->qdict);
1121bb4b9eadSKevin Wolf     monitor_set_cur(qemu_coroutine_self(), NULL);
1122bb4b9eadSKevin Wolf     data->done = true;
1123bb4b9eadSKevin Wolf }
1124bb4b9eadSKevin Wolf 
handle_hmp_command(MonitorHMP * mon,const char * cmdline)1125ed7bda5dSKevin Wolf void handle_hmp_command(MonitorHMP *mon, const char *cmdline)
1126ed7bda5dSKevin Wolf {
1127ed7bda5dSKevin Wolf     QDict *qdict;
1128ed7bda5dSKevin Wolf     const HMPCommand *cmd;
1129ed7bda5dSKevin Wolf     const char *cmd_start = cmdline;
1130ed7bda5dSKevin Wolf 
1131ed7bda5dSKevin Wolf     trace_handle_hmp_command(mon, cmdline);
1132ed7bda5dSKevin Wolf 
1133ed7bda5dSKevin Wolf     cmd = monitor_parse_command(mon, cmdline, &cmdline, hmp_cmds);
1134ed7bda5dSKevin Wolf     if (!cmd) {
1135ed7bda5dSKevin Wolf         return;
1136ed7bda5dSKevin Wolf     }
1137ed7bda5dSKevin Wolf 
1138f9429c67SDaniel P. Berrangé     if (!cmd->cmd && !cmd->cmd_info_hrt) {
1139f0e48cbdSGerd Hoffmann         /* FIXME: is it useful to try autoload modules here ??? */
1140f0e48cbdSGerd Hoffmann         monitor_printf(&mon->common, "Command \"%.*s\" is not available.\n",
1141f0e48cbdSGerd Hoffmann                        (int)(cmdline - cmd_start), cmd_start);
1142f0e48cbdSGerd Hoffmann         return;
1143f0e48cbdSGerd Hoffmann     }
1144f0e48cbdSGerd Hoffmann 
1145ed7bda5dSKevin Wolf     qdict = monitor_parse_arguments(&mon->common, &cmdline, cmd);
1146ed7bda5dSKevin Wolf     if (!qdict) {
1147ed7bda5dSKevin Wolf         while (cmdline > cmd_start && qemu_isspace(cmdline[-1])) {
1148ed7bda5dSKevin Wolf             cmdline--;
1149ed7bda5dSKevin Wolf         }
1150ed7bda5dSKevin Wolf         monitor_printf(&mon->common, "Try \"help %.*s\" for more information\n",
1151ed7bda5dSKevin Wolf                        (int)(cmdline - cmd_start), cmd_start);
1152ed7bda5dSKevin Wolf         return;
1153ed7bda5dSKevin Wolf     }
1154ed7bda5dSKevin Wolf 
1155bb4b9eadSKevin Wolf     if (!cmd->coroutine) {
1156ff04108aSKevin Wolf         /* old_mon is non-NULL when called from qmp_human_monitor_command() */
1157bb4b9eadSKevin Wolf         Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(), &mon->common);
1158f9429c67SDaniel P. Berrangé         handle_hmp_command_exec(&mon->common, cmd, qdict);
1159e69ee454SKevin Wolf         monitor_set_cur(qemu_coroutine_self(), old_mon);
1160bb4b9eadSKevin Wolf     } else {
1161bb4b9eadSKevin Wolf         HandleHmpCommandCo data = {
1162bb4b9eadSKevin Wolf             .mon = &mon->common,
1163bb4b9eadSKevin Wolf             .cmd = cmd,
1164bb4b9eadSKevin Wolf             .qdict = qdict,
1165bb4b9eadSKevin Wolf             .done = false,
1166bb4b9eadSKevin Wolf         };
1167bb4b9eadSKevin Wolf         Coroutine *co = qemu_coroutine_create(handle_hmp_command_co, &data);
1168bb4b9eadSKevin Wolf         monitor_set_cur(co, &mon->common);
1169bb4b9eadSKevin Wolf         aio_co_enter(qemu_get_aio_context(), co);
11706bb68553SStefan Hajnoczi         AIO_WAIT_WHILE_UNLOCKED(NULL, !data.done);
1171bb4b9eadSKevin Wolf     }
1172ff04108aSKevin Wolf 
1173ed7bda5dSKevin Wolf     qobject_unref(qdict);
1174ed7bda5dSKevin Wolf }
1175ed7bda5dSKevin Wolf 
cmd_completion(MonitorHMP * mon,const char * name,const char * list)1176ed7bda5dSKevin Wolf static void cmd_completion(MonitorHMP *mon, const char *name, const char *list)
1177ed7bda5dSKevin Wolf {
1178ed7bda5dSKevin Wolf     const char *p, *pstart;
1179ed7bda5dSKevin Wolf     char cmd[128];
1180ed7bda5dSKevin Wolf     int len;
1181ed7bda5dSKevin Wolf 
1182ed7bda5dSKevin Wolf     p = list;
1183ed7bda5dSKevin Wolf     for (;;) {
1184ed7bda5dSKevin Wolf         pstart = p;
1185ed7bda5dSKevin Wolf         p = qemu_strchrnul(p, '|');
1186ed7bda5dSKevin Wolf         len = p - pstart;
1187ed7bda5dSKevin Wolf         if (len > sizeof(cmd) - 2) {
1188ed7bda5dSKevin Wolf             len = sizeof(cmd) - 2;
1189ed7bda5dSKevin Wolf         }
1190ed7bda5dSKevin Wolf         memcpy(cmd, pstart, len);
1191ed7bda5dSKevin Wolf         cmd[len] = '\0';
119252f50b1eSMarkus Armbruster         readline_add_completion_of(mon->rs, name, cmd);
1193ed7bda5dSKevin Wolf         if (*p == '\0') {
1194ed7bda5dSKevin Wolf             break;
1195ed7bda5dSKevin Wolf         }
1196ed7bda5dSKevin Wolf         p++;
1197ed7bda5dSKevin Wolf     }
1198ed7bda5dSKevin Wolf }
1199ed7bda5dSKevin Wolf 
file_completion(MonitorHMP * mon,const char * input)1200ed7bda5dSKevin Wolf static void file_completion(MonitorHMP *mon, const char *input)
1201ed7bda5dSKevin Wolf {
1202ed7bda5dSKevin Wolf     DIR *ffs;
1203ed7bda5dSKevin Wolf     struct dirent *d;
1204ed7bda5dSKevin Wolf     char path[1024];
1205ed7bda5dSKevin Wolf     char file[1024], file_prefix[1024];
1206ed7bda5dSKevin Wolf     int input_path_len;
1207ed7bda5dSKevin Wolf     const char *p;
1208ed7bda5dSKevin Wolf 
1209ed7bda5dSKevin Wolf     p = strrchr(input, '/');
1210ed7bda5dSKevin Wolf     if (!p) {
1211ed7bda5dSKevin Wolf         input_path_len = 0;
1212ed7bda5dSKevin Wolf         pstrcpy(file_prefix, sizeof(file_prefix), input);
1213ed7bda5dSKevin Wolf         pstrcpy(path, sizeof(path), ".");
1214ed7bda5dSKevin Wolf     } else {
1215ed7bda5dSKevin Wolf         input_path_len = p - input + 1;
1216ed7bda5dSKevin Wolf         memcpy(path, input, input_path_len);
1217ed7bda5dSKevin Wolf         if (input_path_len > sizeof(path) - 1) {
1218ed7bda5dSKevin Wolf             input_path_len = sizeof(path) - 1;
1219ed7bda5dSKevin Wolf         }
1220ed7bda5dSKevin Wolf         path[input_path_len] = '\0';
1221ed7bda5dSKevin Wolf         pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
1222ed7bda5dSKevin Wolf     }
1223ed7bda5dSKevin Wolf 
1224ed7bda5dSKevin Wolf     ffs = opendir(path);
1225ed7bda5dSKevin Wolf     if (!ffs) {
1226ed7bda5dSKevin Wolf         return;
1227ed7bda5dSKevin Wolf     }
1228ed7bda5dSKevin Wolf     for (;;) {
1229ed7bda5dSKevin Wolf         struct stat sb;
1230ed7bda5dSKevin Wolf         d = readdir(ffs);
1231ed7bda5dSKevin Wolf         if (!d) {
1232ed7bda5dSKevin Wolf             break;
1233ed7bda5dSKevin Wolf         }
1234ed7bda5dSKevin Wolf 
1235ed7bda5dSKevin Wolf         if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) {
1236ed7bda5dSKevin Wolf             continue;
1237ed7bda5dSKevin Wolf         }
1238ed7bda5dSKevin Wolf 
1239ed7bda5dSKevin Wolf         if (strstart(d->d_name, file_prefix, NULL)) {
1240ed7bda5dSKevin Wolf             memcpy(file, input, input_path_len);
1241ed7bda5dSKevin Wolf             if (input_path_len < sizeof(file)) {
1242ed7bda5dSKevin Wolf                 pstrcpy(file + input_path_len, sizeof(file) - input_path_len,
1243ed7bda5dSKevin Wolf                         d->d_name);
1244ed7bda5dSKevin Wolf             }
1245ed7bda5dSKevin Wolf             /*
1246ed7bda5dSKevin Wolf              * stat the file to find out if it's a directory.
1247ed7bda5dSKevin Wolf              * In that case add a slash to speed up typing long paths
1248ed7bda5dSKevin Wolf              */
1249ed7bda5dSKevin Wolf             if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) {
1250ed7bda5dSKevin Wolf                 pstrcat(file, sizeof(file), "/");
1251ed7bda5dSKevin Wolf             }
1252ed7bda5dSKevin Wolf             readline_add_completion(mon->rs, file);
1253ed7bda5dSKevin Wolf         }
1254ed7bda5dSKevin Wolf     }
1255ed7bda5dSKevin Wolf     closedir(ffs);
1256ed7bda5dSKevin Wolf }
1257ed7bda5dSKevin Wolf 
next_arg_type(const char * typestr)1258ed7bda5dSKevin Wolf static const char *next_arg_type(const char *typestr)
1259ed7bda5dSKevin Wolf {
1260ed7bda5dSKevin Wolf     const char *p = strchr(typestr, ':');
1261ed7bda5dSKevin Wolf     return (p != NULL ? ++p : typestr);
1262ed7bda5dSKevin Wolf }
1263ed7bda5dSKevin Wolf 
monitor_find_completion_by_table(MonitorHMP * mon,const HMPCommand * cmd_table,char ** args,int nb_args)1264ed7bda5dSKevin Wolf static void monitor_find_completion_by_table(MonitorHMP *mon,
1265ed7bda5dSKevin Wolf                                              const HMPCommand *cmd_table,
1266ed7bda5dSKevin Wolf                                              char **args,
1267ed7bda5dSKevin Wolf                                              int nb_args)
1268ed7bda5dSKevin Wolf {
1269ed7bda5dSKevin Wolf     const char *cmdname;
1270ed7bda5dSKevin Wolf     int i;
127152f50b1eSMarkus Armbruster     const char *ptype, *old_ptype, *str;
1272ed7bda5dSKevin Wolf     const HMPCommand *cmd;
1273ed7bda5dSKevin Wolf     BlockBackend *blk = NULL;
1274ed7bda5dSKevin Wolf 
1275ed7bda5dSKevin Wolf     if (nb_args <= 1) {
1276ed7bda5dSKevin Wolf         /* command completion */
1277ed7bda5dSKevin Wolf         if (nb_args == 0) {
1278ed7bda5dSKevin Wolf             cmdname = "";
1279ed7bda5dSKevin Wolf         } else {
1280ed7bda5dSKevin Wolf             cmdname = args[0];
1281ed7bda5dSKevin Wolf         }
1282ed7bda5dSKevin Wolf         readline_set_completion_index(mon->rs, strlen(cmdname));
1283ed7bda5dSKevin Wolf         for (cmd = cmd_table; cmd->name != NULL; cmd++) {
12844cd29274SPaolo Bonzini             if (cmd_available(cmd)) {
1285ed7bda5dSKevin Wolf                 cmd_completion(mon, cmdname, cmd->name);
1286ed7bda5dSKevin Wolf             }
1287ed7bda5dSKevin Wolf         }
1288ed7bda5dSKevin Wolf     } else {
1289ed7bda5dSKevin Wolf         /* find the command */
1290ed7bda5dSKevin Wolf         for (cmd = cmd_table; cmd->name != NULL; cmd++) {
1291ed7bda5dSKevin Wolf             if (hmp_compare_cmd(args[0], cmd->name) &&
12924cd29274SPaolo Bonzini                 cmd_available(cmd)) {
1293ed7bda5dSKevin Wolf                 break;
1294ed7bda5dSKevin Wolf             }
1295ed7bda5dSKevin Wolf         }
1296ed7bda5dSKevin Wolf         if (!cmd->name) {
1297ed7bda5dSKevin Wolf             return;
1298ed7bda5dSKevin Wolf         }
1299ed7bda5dSKevin Wolf 
1300ed7bda5dSKevin Wolf         if (cmd->sub_table) {
1301ed7bda5dSKevin Wolf             /* do the job again */
1302ed7bda5dSKevin Wolf             monitor_find_completion_by_table(mon, cmd->sub_table,
1303ed7bda5dSKevin Wolf                                              &args[1], nb_args - 1);
1304ed7bda5dSKevin Wolf             return;
1305ed7bda5dSKevin Wolf         }
1306ed7bda5dSKevin Wolf         if (cmd->command_completion) {
1307ed7bda5dSKevin Wolf             cmd->command_completion(mon->rs, nb_args, args[nb_args - 1]);
1308ed7bda5dSKevin Wolf             return;
1309ed7bda5dSKevin Wolf         }
1310ed7bda5dSKevin Wolf 
1311ed7bda5dSKevin Wolf         ptype = next_arg_type(cmd->args_type);
1312ed7bda5dSKevin Wolf         for (i = 0; i < nb_args - 2; i++) {
1313ed7bda5dSKevin Wolf             if (*ptype != '\0') {
1314ed7bda5dSKevin Wolf                 ptype = next_arg_type(ptype);
1315ed7bda5dSKevin Wolf                 while (*ptype == '?') {
1316ed7bda5dSKevin Wolf                     ptype = next_arg_type(ptype);
1317ed7bda5dSKevin Wolf                 }
1318ed7bda5dSKevin Wolf             }
1319ed7bda5dSKevin Wolf         }
1320ed7bda5dSKevin Wolf         str = args[nb_args - 1];
1321ed7bda5dSKevin Wolf         old_ptype = NULL;
1322ed7bda5dSKevin Wolf         while (*ptype == '-' && old_ptype != ptype) {
1323ed7bda5dSKevin Wolf             old_ptype = ptype;
1324ed7bda5dSKevin Wolf             ptype = next_arg_type(ptype);
1325ed7bda5dSKevin Wolf         }
1326ed7bda5dSKevin Wolf         switch (*ptype) {
1327ed7bda5dSKevin Wolf         case 'F':
1328ed7bda5dSKevin Wolf             /* file completion */
1329ed7bda5dSKevin Wolf             readline_set_completion_index(mon->rs, strlen(str));
1330ed7bda5dSKevin Wolf             file_completion(mon, str);
1331ed7bda5dSKevin Wolf             break;
1332ed7bda5dSKevin Wolf         case 'B':
1333ed7bda5dSKevin Wolf             /* block device name completion */
1334ed7bda5dSKevin Wolf             readline_set_completion_index(mon->rs, strlen(str));
1335ed7bda5dSKevin Wolf             while ((blk = blk_next(blk)) != NULL) {
133652f50b1eSMarkus Armbruster                 readline_add_completion_of(mon->rs, str, blk_name(blk));
1337ed7bda5dSKevin Wolf             }
1338ed7bda5dSKevin Wolf             break;
1339ed7bda5dSKevin Wolf         case 's':
1340ed7bda5dSKevin Wolf         case 'S':
1341ed7bda5dSKevin Wolf             if (!strcmp(cmd->name, "help|?")) {
1342ed7bda5dSKevin Wolf                 monitor_find_completion_by_table(mon, cmd_table,
1343ed7bda5dSKevin Wolf                                                  &args[1], nb_args - 1);
1344ed7bda5dSKevin Wolf             }
1345ed7bda5dSKevin Wolf             break;
1346ed7bda5dSKevin Wolf         default:
1347ed7bda5dSKevin Wolf             break;
1348ed7bda5dSKevin Wolf         }
1349ed7bda5dSKevin Wolf     }
1350ed7bda5dSKevin Wolf }
1351ed7bda5dSKevin Wolf 
monitor_find_completion(void * opaque,const char * cmdline)1352ed7bda5dSKevin Wolf static void monitor_find_completion(void *opaque,
1353ed7bda5dSKevin Wolf                                     const char *cmdline)
1354ed7bda5dSKevin Wolf {
1355ed7bda5dSKevin Wolf     MonitorHMP *mon = opaque;
1356ed7bda5dSKevin Wolf     char *args[MAX_ARGS];
1357ed7bda5dSKevin Wolf     int nb_args, len;
1358ed7bda5dSKevin Wolf 
1359ed7bda5dSKevin Wolf     /* 1. parse the cmdline */
1360ed7bda5dSKevin Wolf     if (parse_cmdline(cmdline, &nb_args, args) < 0) {
1361ed7bda5dSKevin Wolf         return;
1362ed7bda5dSKevin Wolf     }
1363ed7bda5dSKevin Wolf 
1364ed7bda5dSKevin Wolf     /*
1365ed7bda5dSKevin Wolf      * if the line ends with a space, it means we want to complete the
1366ed7bda5dSKevin Wolf      * next arg
1367ed7bda5dSKevin Wolf      */
1368ed7bda5dSKevin Wolf     len = strlen(cmdline);
1369ed7bda5dSKevin Wolf     if (len > 0 && qemu_isspace(cmdline[len - 1])) {
1370ed7bda5dSKevin Wolf         if (nb_args >= MAX_ARGS) {
1371ed7bda5dSKevin Wolf             goto cleanup;
1372ed7bda5dSKevin Wolf         }
1373ed7bda5dSKevin Wolf         args[nb_args++] = g_strdup("");
1374ed7bda5dSKevin Wolf     }
1375ed7bda5dSKevin Wolf 
1376ed7bda5dSKevin Wolf     /* 2. auto complete according to args */
1377ed7bda5dSKevin Wolf     monitor_find_completion_by_table(mon, hmp_cmds, args, nb_args);
1378ed7bda5dSKevin Wolf 
1379ed7bda5dSKevin Wolf cleanup:
1380ed7bda5dSKevin Wolf     free_cmdline_args(args, nb_args);
1381ed7bda5dSKevin Wolf }
1382ed7bda5dSKevin Wolf 
monitor_read(void * opaque,const uint8_t * buf,int size)1383ed7bda5dSKevin Wolf static void monitor_read(void *opaque, const uint8_t *buf, int size)
1384ed7bda5dSKevin Wolf {
1385947e4744SKevin Wolf     MonitorHMP *mon = container_of(opaque, MonitorHMP, common);
1386ed7bda5dSKevin Wolf     int i;
1387ed7bda5dSKevin Wolf 
1388ed7bda5dSKevin Wolf     if (mon->rs) {
1389ed7bda5dSKevin Wolf         for (i = 0; i < size; i++) {
1390ed7bda5dSKevin Wolf             readline_handle_byte(mon->rs, buf[i]);
1391ed7bda5dSKevin Wolf         }
1392ed7bda5dSKevin Wolf     } else {
1393ed7bda5dSKevin Wolf         if (size == 0 || buf[size - 1] != 0) {
1394947e4744SKevin Wolf             monitor_printf(&mon->common, "corrupted command\n");
1395ed7bda5dSKevin Wolf         } else {
1396ed7bda5dSKevin Wolf             handle_hmp_command(mon, (char *)buf);
1397ed7bda5dSKevin Wolf         }
1398ed7bda5dSKevin Wolf     }
1399ed7bda5dSKevin Wolf }
1400ed7bda5dSKevin Wolf 
monitor_event(void * opaque,QEMUChrEvent event)1401083b266fSPhilippe Mathieu-Daudé static void monitor_event(void *opaque, QEMUChrEvent event)
1402ed7bda5dSKevin Wolf {
1403ed7bda5dSKevin Wolf     Monitor *mon = opaque;
1404ed7bda5dSKevin Wolf 
1405ed7bda5dSKevin Wolf     switch (event) {
1406ed7bda5dSKevin Wolf     case CHR_EVENT_MUX_IN:
1407ed7bda5dSKevin Wolf         qemu_mutex_lock(&mon->mon_lock);
14086ee7c82dSPaolo Bonzini         if (mon->mux_out) {
1409ed7bda5dSKevin Wolf             mon->mux_out = 0;
1410ed7bda5dSKevin Wolf             monitor_resume(mon);
1411ed7bda5dSKevin Wolf         }
14126ee7c82dSPaolo Bonzini         qemu_mutex_unlock(&mon->mon_lock);
1413ed7bda5dSKevin Wolf         break;
1414ed7bda5dSKevin Wolf 
1415ed7bda5dSKevin Wolf     case CHR_EVENT_MUX_OUT:
1416ed7bda5dSKevin Wolf         qemu_mutex_lock(&mon->mon_lock);
14176ee7c82dSPaolo Bonzini         if (!mon->mux_out) {
14186ee7c82dSPaolo Bonzini             if (mon->reset_seen && !mon->suspend_cnt) {
14196ee7c82dSPaolo Bonzini                 monitor_puts_locked(mon, "\n");
14206ee7c82dSPaolo Bonzini             } else {
14216ee7c82dSPaolo Bonzini                 monitor_flush_locked(mon);
14226ee7c82dSPaolo Bonzini             }
14236ee7c82dSPaolo Bonzini             monitor_suspend(mon);
1424ed7bda5dSKevin Wolf             mon->mux_out = 1;
14256ee7c82dSPaolo Bonzini         }
1426ed7bda5dSKevin Wolf         qemu_mutex_unlock(&mon->mon_lock);
1427ed7bda5dSKevin Wolf         break;
1428ed7bda5dSKevin Wolf 
1429ed7bda5dSKevin Wolf     case CHR_EVENT_OPENED:
1430ed7bda5dSKevin Wolf         monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
1431ed7bda5dSKevin Wolf                        "information\n", QEMU_VERSION);
14326ee7c82dSPaolo Bonzini         qemu_mutex_lock(&mon->mon_lock);
1433ed7bda5dSKevin Wolf         mon->reset_seen = 1;
14346ee7c82dSPaolo Bonzini         if (!mon->mux_out) {
14356ee7c82dSPaolo Bonzini             /* Suspend-resume forces the prompt to be printed.  */
14366ee7c82dSPaolo Bonzini             monitor_suspend(mon);
14376ee7c82dSPaolo Bonzini             monitor_resume(mon);
14386ee7c82dSPaolo Bonzini         }
14396ee7c82dSPaolo Bonzini         qemu_mutex_unlock(&mon->mon_lock);
1440ed7bda5dSKevin Wolf         mon_refcount++;
1441ed7bda5dSKevin Wolf         break;
1442ed7bda5dSKevin Wolf 
1443ed7bda5dSKevin Wolf     case CHR_EVENT_CLOSED:
1444ed7bda5dSKevin Wolf         mon_refcount--;
1445ed7bda5dSKevin Wolf         monitor_fdsets_cleanup();
1446ed7bda5dSKevin Wolf         break;
14474904ca6aSPhilippe Mathieu-Daudé 
14484904ca6aSPhilippe Mathieu-Daudé     case CHR_EVENT_BREAK:
14494904ca6aSPhilippe Mathieu-Daudé         /* Ignored */
14504904ca6aSPhilippe Mathieu-Daudé         break;
1451ed7bda5dSKevin Wolf     }
1452ed7bda5dSKevin Wolf }
1453ed7bda5dSKevin Wolf 
1454ed7bda5dSKevin Wolf 
1455ed7bda5dSKevin Wolf /*
1456ed7bda5dSKevin Wolf  * These functions just adapt the readline interface in a typesafe way.  We
1457ed7bda5dSKevin Wolf  * could cast function pointers but that discards compiler checks.
1458ed7bda5dSKevin Wolf  */
monitor_readline_printf(void * opaque,const char * fmt,...)14599edc6313SMarc-André Lureau static void G_GNUC_PRINTF(2, 3) monitor_readline_printf(void *opaque,
1460ed7bda5dSKevin Wolf                                                        const char *fmt, ...)
1461ed7bda5dSKevin Wolf {
1462ed7bda5dSKevin Wolf     MonitorHMP *mon = opaque;
1463ed7bda5dSKevin Wolf     va_list ap;
1464ed7bda5dSKevin Wolf     va_start(ap, fmt);
1465ed7bda5dSKevin Wolf     monitor_vprintf(&mon->common, fmt, ap);
1466ed7bda5dSKevin Wolf     va_end(ap);
1467ed7bda5dSKevin Wolf }
1468ed7bda5dSKevin Wolf 
monitor_readline_flush(void * opaque)1469ed7bda5dSKevin Wolf static void monitor_readline_flush(void *opaque)
1470ed7bda5dSKevin Wolf {
1471ed7bda5dSKevin Wolf     MonitorHMP *mon = opaque;
1472ed7bda5dSKevin Wolf     monitor_flush(&mon->common);
1473ed7bda5dSKevin Wolf }
1474ed7bda5dSKevin Wolf 
monitor_init_hmp(Chardev * chr,bool use_readline,Error ** errp)14758e9119a8SKevin Wolf void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp)
1476ed7bda5dSKevin Wolf {
1477ed7bda5dSKevin Wolf     MonitorHMP *mon = g_new0(MonitorHMP, 1);
1478ed7bda5dSKevin Wolf 
14798e9119a8SKevin Wolf     if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
14808e9119a8SKevin Wolf         g_free(mon);
14818e9119a8SKevin Wolf         return;
14828e9119a8SKevin Wolf     }
14838e9119a8SKevin Wolf 
148492082416SKevin Wolf     monitor_data_init(&mon->common, false, false, false);
1485ed7bda5dSKevin Wolf 
1486fbfc29e3SKevin Wolf     mon->use_readline = use_readline;
148792082416SKevin Wolf     if (mon->use_readline) {
1488ed7bda5dSKevin Wolf         mon->rs = readline_init(monitor_readline_printf,
1489ed7bda5dSKevin Wolf                                 monitor_readline_flush,
1490ed7bda5dSKevin Wolf                                 mon,
1491ed7bda5dSKevin Wolf                                 monitor_find_completion);
1492ed7bda5dSKevin Wolf         monitor_read_command(mon, 0);
1493ed7bda5dSKevin Wolf     }
1494ed7bda5dSKevin Wolf 
1495ed7bda5dSKevin Wolf     qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read, monitor_read,
1496ed7bda5dSKevin Wolf                              monitor_event, NULL, &mon->common, NULL, true);
1497ed7bda5dSKevin Wolf     monitor_list_append(&mon->common);
1498ed7bda5dSKevin Wolf }
1499