struct Monitor {
CharDriverState *chr;
+ int flags;
+ int suspend_cnt;
+ uint8_t outbuf[1024];
+ int outbuf_index;
+ ReadLineState *rs;
+ CPUState *mon_cpu;
+ BlockDriverCompletionFunc *password_completion_cb;
+ void *password_opaque;
LIST_ENTRY(Monitor) entry;
};
static const mon_cmd_t mon_cmds[];
static const mon_cmd_t info_cmds[];
-static uint8_t term_outbuf[1024];
-static int term_outbuf_index;
-static BlockDriverCompletionFunc *password_completion_cb;
-static void *password_opaque;
-ReadLineState *rs;
-
Monitor *cur_mon = NULL;
-static void monitor_start_input(void);
+static void monitor_command_cb(Monitor *mon, const char *cmdline,
+ void *opaque);
-static CPUState *mon_cpu = NULL;
+static void monitor_read_command(Monitor *mon, int show_prompt)
+{
+ readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
+ if (show_prompt)
+ readline_show_prompt(mon->rs);
+}
static void monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
void *opaque)
{
- readline_start(rs, "Password: ", 1, readline_func, opaque);
+ readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
+ /* prompt is printed on return from the command handler */
}
void monitor_flush(Monitor *mon)
{
- Monitor *m;
-
- if (term_outbuf_index > 0) {
- LIST_FOREACH(m, &mon_list, entry) {
- if (m->chr->focus == 0)
- qemu_chr_write(m->chr, term_outbuf, term_outbuf_index);
- }
- term_outbuf_index = 0;
+ if (mon && mon->outbuf_index != 0 && mon->chr->focus == 0) {
+ qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
+ mon->outbuf_index = 0;
}
}
static void monitor_puts(Monitor *mon, const char *str)
{
char c;
+
+ if (!mon)
+ return;
+
for(;;) {
c = *str++;
if (c == '\0')
break;
if (c == '\n')
- term_outbuf[term_outbuf_index++] = '\r';
- term_outbuf[term_outbuf_index++] = c;
- if (term_outbuf_index >= (sizeof(term_outbuf) - 1) ||
- c == '\n')
+ mon->outbuf[mon->outbuf_index++] = '\r';
+ mon->outbuf[mon->outbuf_index++] = c;
+ if (mon->outbuf_index >= (sizeof(mon->outbuf) - 1)
+ || c == '\n')
monitor_flush(mon);
}
}
for(env = first_cpu; env != NULL; env = env->next_cpu) {
if (env->cpu_index == cpu_index) {
- mon_cpu = env;
+ cur_mon->mon_cpu = env;
return 0;
}
}
static CPUState *mon_get_cpu(void)
{
- if (!mon_cpu) {
+ if (!cur_mon->mon_cpu) {
mon_set_cpu(0);
}
- return mon_cpu;
+ return cur_mon->mon_cpu;
}
static void do_info_registers(Monitor *mon)
for(env = first_cpu; env != NULL; env = env->next_cpu) {
monitor_printf(mon, "%c CPU #%d:",
- (env == mon_cpu) ? '*' : ' ',
+ (env == mon->mon_cpu) ? '*' : ' ',
env->cpu_index);
#if defined(TARGET_I386)
monitor_printf(mon, " pc=0x" TARGET_FMT_lx,
i = 0;
for(;;) {
- str = readline_get_history(rs, i);
+ str = readline_get_history(mon->rs, i);
if (!str)
break;
monitor_printf(mon, "%d: '%s'\n", i, str);
if (vnc_display_password(NULL, password) < 0)
monitor_printf(mon, "could not set VNC server password\n");
- monitor_start_input();
+ monitor_read_command(mon, 1);
}
static void do_change_vnc(Monitor *mon, const char *target, const char *arg)
memcpy(cmd, pstart, len);
cmd[len] = '\0';
if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
- readline_add_completion(rs, cmd);
+ readline_add_completion(cur_mon->rs, cmd);
}
if (*p == '\0')
break;
stat(file, &sb);
if(S_ISDIR(sb.st_mode))
pstrcat(file, sizeof(file), "/");
- readline_add_completion(rs, file);
+ readline_add_completion(cur_mon->rs, file);
}
}
closedir(ffs);
if (input[0] == '\0' ||
!strncmp(name, (char *)input, strlen(input))) {
- readline_add_completion(rs, name);
+ readline_add_completion(cur_mon->rs, name);
}
}
cmdname = "";
else
cmdname = args[0];
- readline_set_completion_index(rs, strlen(cmdname));
+ readline_set_completion_index(cur_mon->rs, strlen(cmdname));
for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
cmd_completion(cmdname, cmd->name);
}
switch(*ptype) {
case 'F':
/* file completion */
- readline_set_completion_index(rs, strlen(str));
+ readline_set_completion_index(cur_mon->rs, strlen(str));
file_completion(str);
break;
case 'B':
/* block device name completion */
- readline_set_completion_index(rs, strlen(str));
+ readline_set_completion_index(cur_mon->rs, strlen(str));
bdrv_iterate(block_completion_it, (void *)str);
break;
case 's':
/* XXX: more generic ? */
if (!strcmp(cmd->name, "info")) {
- readline_set_completion_index(rs, strlen(str));
+ readline_set_completion_index(cur_mon->rs, strlen(str));
for(cmd = info_cmds; cmd->name != NULL; cmd++) {
cmd_completion(str, cmd->name);
}
} else if (!strcmp(cmd->name, "sendkey")) {
- readline_set_completion_index(rs, strlen(str));
+ readline_set_completion_index(cur_mon->rs, strlen(str));
for(key = key_defs; key->name != NULL; key++) {
cmd_completion(str, key->name);
}
qemu_free(args[i]);
}
-static int term_can_read(void *opaque)
+static int monitor_can_read(void *opaque)
{
- return 128;
+ Monitor *mon = opaque;
+
+ return (mon->suspend_cnt == 0) ? 128 : 0;
}
-static void term_read(void *opaque, const uint8_t *buf, int size)
+static void monitor_read(void *opaque, const uint8_t *buf, int size)
{
+ Monitor *old_mon = cur_mon;
int i;
- for(i = 0; i < size; i++)
- readline_handle_byte(rs, buf[i]);
-}
+ cur_mon = opaque;
+
+ for (i = 0; i < size; i++)
+ readline_handle_byte(cur_mon->rs, buf[i]);
-static int monitor_suspended;
+ cur_mon = old_mon;
+}
static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque)
{
+ monitor_suspend(mon);
monitor_handle_command(mon, cmdline);
- if (!monitor_suspended)
- readline_show_prompt(rs);
- else
- monitor_suspended = 2;
+ monitor_resume(mon);
}
void monitor_suspend(Monitor *mon)
{
- monitor_suspended = 1;
+ mon->suspend_cnt++;
}
void monitor_resume(Monitor *mon)
{
- if (monitor_suspended == 2)
- monitor_start_input();
- monitor_suspended = 0;
+ if (--mon->suspend_cnt == 0)
+ readline_show_prompt(mon->rs);
}
-static void monitor_start_input(void)
-{
- readline_start(rs, "(qemu) ", 0, monitor_command_cb, NULL);
- readline_show_prompt(rs);
-}
-
-static void term_event(void *opaque, int event)
+static void monitor_event(void *opaque, int event)
{
Monitor *mon = opaque;
monitor_printf(mon, "QEMU %s monitor - type 'help' for more information\n",
QEMU_VERSION);
- monitor_start_input();
+ readline_show_prompt(mon->rs);
}
-static int is_first_init = 1;
-
-void monitor_init(CharDriverState *chr)
+void monitor_init(CharDriverState *chr, int flags)
{
+ static int is_first_init = 1;
Monitor *mon;
if (is_first_init) {
mon = qemu_mallocz(sizeof(*mon));
mon->chr = chr;
- rs = readline_init(mon, monitor_find_completion);
+ mon->flags = flags;
+ mon->rs = readline_init(mon, monitor_find_completion);
+ monitor_read_command(mon, 0);
- qemu_chr_add_handlers(chr, term_can_read, term_read, term_event, mon);
+ qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event,
+ mon);
LIST_INSERT_HEAD(&mon_list, mon, entry);
- if (!cur_mon)
+ if (!cur_mon || (flags & MONITOR_IS_DEFAULT))
cur_mon = mon;
-
- readline_start(rs, "", 0, monitor_command_cb, NULL);
}
static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
monitor_printf(mon, "invalid password\n");
ret = -EPERM;
}
- if (password_completion_cb)
- password_completion_cb(password_opaque, ret);
+ if (mon->password_completion_cb)
+ mon->password_completion_cb(mon->password_opaque, ret);
- monitor_start_input();
+ monitor_read_command(mon, 1);
}
void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
bdrv_get_encrypted_filename(bs));
- password_completion_cb = completion_cb;
- password_opaque = opaque;
+ mon->password_completion_cb = completion_cb;
+ mon->password_opaque = opaque;
monitor_read_password(mon, bdrv_password_cb, bs);
}