From e92bc56ef89ab8b51c4c89d4d9779b64e9491b9b Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Tue, 7 Sep 2010 06:21:25 -0700 Subject: Add new "qemu monitor" command to the console. This allows you to access the QEMU virtual machine monitor directly from the console (instead of playing with the command-line to do it). The implementation of the 'quit' command has been modified to simply close the connection, instead of stopping the emulator program. This patch introduces changes that allow a console session to be detached and redirected at runtime to other internal services of the emulator program. This will be useful in the future to implement other features. + doc typo + add proper definitions for CONFIG_ANDROID on config-host.h + remove obsolete sysdeps.h dependency in android/console.c Change-Id: If16cfe41c12a26eb8f56e3a9c24452eafa5efab4 --- monitor.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'monitor.c') diff --git a/monitor.c b/monitor.c index f640bf8..3c23397 100644 --- a/monitor.c +++ b/monitor.c @@ -70,6 +70,8 @@ typedef struct mon_cmd_t { const char *help; } mon_cmd_t; +#define MON_CMD_T_INITIALIZER { NULL, NULL, NULL, NULL, NULL } + struct Monitor { CharDriverState *chr; int flags; @@ -81,6 +83,7 @@ struct Monitor { BlockDriverCompletionFunc *password_completion_cb; void *password_opaque; QLIST_ENTRY(Monitor) entry; + int has_quit; }; static QLIST_HEAD(mon_list, Monitor) mon_list; @@ -409,7 +412,11 @@ static void do_info_cpu_stats(Monitor *mon) static void do_quit(Monitor *mon) { - exit(0); + if ((mon->flags & MONITOR_QUIT_DOESNT_EXIT) == 0) { + exit(0); + } + /* we cannot destroy the monitor just yet, so flag it instead */ + mon->has_quit = 1; } static int eject_device(Monitor *mon, BlockDriverState *bs, int force) @@ -1661,7 +1668,7 @@ static void do_acl(Monitor *mon, static const mon_cmd_t mon_cmds[] = { #include "qemu-monitor.h" - { NULL, NULL, }, + MON_CMD_T_INITIALIZER }; /* Please update qemu-monitor.hx when adding or changing commands */ @@ -1741,7 +1748,7 @@ static const mon_cmd_t info_cmds[] = { "", "show balloon information" }, { "qtree", "", do_info_qtree, "", "show device tree" }, - { NULL, NULL, }, + MON_CMD_T_INITIALIZER }; /*******************************************************************/ @@ -1759,6 +1766,8 @@ typedef struct MonitorDef { int type; } MonitorDef; +#define MONITOR_DEF_INITIALIZER { NULL, 0, NULL, 0 } + #if defined(TARGET_I386) static target_long monitor_get_pc (const struct MonitorDef *md, int val) { @@ -2085,7 +2094,7 @@ static const MonitorDef monitor_defs[] = { { "fprs", offsetof(CPUState, fprs) }, #endif #endif - { NULL }, + MONITOR_DEF_INITIALIZER }; static void expr_error(Monitor *mon, const char *msg) @@ -2938,6 +2947,8 @@ static int monitor_can_read(void *opaque) return (mon->suspend_cnt == 0) ? 128 : 0; } +static void monitor_done(Monitor *mon); // forward + static void monitor_read(void *opaque, const uint8_t *buf, int size) { Monitor *old_mon = cur_mon; @@ -2955,6 +2966,9 @@ static void monitor_read(void *opaque, const uint8_t *buf, int size) monitor_handle_command(cur_mon, (char *)buf); } + if (cur_mon->has_quit) { + monitor_done(cur_mon); + } cur_mon = old_mon; } @@ -3046,6 +3060,19 @@ void monitor_init(CharDriverState *chr, int flags) cur_mon = mon; } +static void monitor_done(Monitor *mon) +{ + if (cur_mon == mon) + cur_mon = NULL; + + QLIST_REMOVE(mon, entry); + + readline_free(mon->rs); + qemu_chr_close(mon->chr); + + qemu_free(mon); +} + static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque) { BlockDriverState *bs = opaque; -- cgit v1.1