diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 146 |
1 files changed, 75 insertions, 71 deletions
@@ -69,6 +69,14 @@ typedef struct mon_cmd_t { 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; }; @@ -77,34 +85,30 @@ static LIST_HEAD(mon_list, Monitor) mon_list; 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; } } @@ -112,15 +116,19 @@ void monitor_flush(Monitor *mon) 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); } } @@ -291,7 +299,7 @@ static int mon_set_cpu(int cpu_index) 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; } } @@ -300,10 +308,10 @@ static int mon_set_cpu(int cpu_index) 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) @@ -330,7 +338,7 @@ static void do_info_cpus(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, @@ -367,7 +375,7 @@ static void do_info_history(Monitor *mon) 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); @@ -451,7 +459,7 @@ static void change_vnc_password_cb(Monitor *mon, const char *password, 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) @@ -2688,7 +2696,7 @@ static void cmd_completion(const char *name, const char *list) 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; @@ -2741,7 +2749,7 @@ static void file_completion(const char *input) 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); @@ -2754,7 +2762,7 @@ static void block_completion_it(void *opaque, BlockDriverState *bs) if (input[0] == '\0' || !strncmp(name, (char *)input, strlen(input))) { - readline_add_completion(rs, name); + readline_add_completion(cur_mon->rs, name); } } @@ -2814,7 +2822,7 @@ static void monitor_find_completion(const char *cmdline) 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); } @@ -2838,23 +2846,23 @@ static void monitor_find_completion(const char *cmdline) 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); } @@ -2868,49 +2876,45 @@ static void monitor_find_completion(const char *cmdline) 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; @@ -2919,13 +2923,12 @@ static void term_event(void *opaque, int event) 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) { @@ -2936,15 +2939,16 @@ void monitor_init(CharDriverState *chr) 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) @@ -2956,10 +2960,10 @@ 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, @@ -2975,8 +2979,8 @@ 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); } |