]>
git.proxmox.com Git - mirror_qemu.git/blob - monitor.c
4 * Copyright (c) 2003-2004 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47 #define TERM_CMD_BUF_SIZE 4095
54 #define printf do_not_use_printf
56 static char term_cmd_buf
[TERM_CMD_BUF_SIZE
+ 1];
57 static int term_cmd_buf_index
;
58 static int term_cmd_buf_size
;
59 static int term_esc_state
;
60 static int term_esc_param
;
62 typedef struct term_cmd_t
{
64 void (*handler
)(int argc
, const char **argv
);
69 static term_cmd_t term_cmds
[];
70 static term_cmd_t info_cmds
[];
72 void term_printf(const char *fmt
, ...)
85 static int compare_cmd(const char *name
, const char *list
)
87 const char *p
, *pstart
;
95 p
= pstart
+ strlen(pstart
);
96 if ((p
- pstart
) == len
&& !memcmp(pstart
, name
, len
))
105 static void help_cmd1(term_cmd_t
*cmds
, const char *prefix
, const char *name
)
109 for(cmd
= cmds
; cmd
->name
!= NULL
; cmd
++) {
110 if (!name
|| !strcmp(name
, cmd
->name
))
111 term_printf("%s%s %s -- %s\n", prefix
, cmd
->name
, cmd
->params
, cmd
->help
);
115 static void help_cmd(const char *name
)
117 if (name
&& !strcmp(name
, "info")) {
118 help_cmd1(info_cmds
, "info ", NULL
);
120 help_cmd1(term_cmds
, "", name
);
121 if (name
&& !strcmp(name
, "log")) {
123 term_printf("Log items (comma separated):\n");
124 term_printf("%-10s %s\n", "none", "remove all logs");
125 for(item
= cpu_log_items
; item
->mask
!= 0; item
++) {
126 term_printf("%-10s %s\n", item
->name
, item
->help
);
132 static void do_help(int argc
, const char **argv
)
137 static void do_commit(int argc
, const char **argv
)
141 for (i
= 0; i
< MAX_DISKS
; i
++) {
143 bdrv_commit(bs_table
[i
]);
147 static void do_info(int argc
, const char **argv
)
155 for(cmd
= info_cmds
; cmd
->name
!= NULL
; cmd
++) {
156 if (compare_cmd(argv
[1], cmd
->name
))
163 cmd
->handler(argc
, argv
);
166 static void do_info_network(int argc
, const char **argv
)
171 for(i
= 0; i
< nb_nics
; i
++) {
173 term_printf("%d: ifname=%s macaddr=", i
, nd
->ifname
);
174 for(j
= 0; j
< 6; j
++) {
177 term_printf("%02x", nd
->macaddr
[j
]);
183 static void do_info_block(int argc
, const char **argv
)
188 static void do_quit(int argc
, const char **argv
)
193 static int eject_device(BlockDriverState
*bs
, int force
)
195 if (bdrv_is_inserted(bs
)) {
197 if (!bdrv_is_removable(bs
)) {
198 term_printf("device is not removable\n");
201 if (bdrv_is_locked(bs
)) {
202 term_printf("device is locked\n");
211 static void do_eject(int argc
, const char **argv
)
213 BlockDriverState
*bs
;
224 if (!strcmp(*parg
, "-f")) {
230 bs
= bdrv_find(*parg
);
232 term_printf("device not found\n");
235 eject_device(bs
, force
);
238 static void do_change(int argc
, const char **argv
)
240 BlockDriverState
*bs
;
246 bs
= bdrv_find(argv
[1]);
248 term_printf("device not found\n");
251 if (eject_device(bs
, 0) < 0)
253 bdrv_open(bs
, argv
[2], 0);
256 static void do_screen_dump(int argc
, const char **argv
)
262 vga_screen_dump(argv
[1]);
265 static void do_log(int argc
, const char **argv
)
271 if (!strcmp(argv
[1], "none")) {
274 mask
= cpu_str_to_log_mask(argv
[1]);
284 static term_cmd_t term_cmds
[] = {
286 "[cmd]", "show the help" },
287 { "commit", do_commit
,
288 "", "commit changes to the disk images (if -snapshot is used)" },
290 "subcommand", "show various information about the system state" },
292 "", "quit the emulator" },
294 "[-f] device", "eject a removable media (use -f to force it)" },
295 { "change", do_change
,
296 "device filename", "change a removable media" },
297 { "screendump", do_screen_dump
,
298 "filename", "save screen into PPM image 'filename'" },
300 "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
304 static term_cmd_t info_cmds
[] = {
305 { "network", do_info_network
,
306 "", "show the network state" },
307 { "block", do_info_block
,
308 "", "show the block devices" },
312 static void term_handle_command(char *cmdline
)
316 const char *args
[MAX_ARGS
+ 1];
320 term_printf("command='%s'\n", cmdline
);
323 /* split command in words */
332 while (*p
!= '\0' && !isspace(*p
))
336 if (argc
>= MAX_ARGS
)
344 for(i
=0;i
<argc
;i
++) {
345 term_printf(" '%s'", args
[i
]);
351 for(cmd
= term_cmds
; cmd
->name
!= NULL
; cmd
++) {
352 if (compare_cmd(args
[0], cmd
->name
))
355 term_printf("unknown command: '%s'\n", args
[0]);
358 cmd
->handler(argc
, args
);
361 static void term_show_prompt(void)
363 term_printf("(qemu) ");
365 term_cmd_buf_index
= 0;
366 term_cmd_buf_size
= 0;
367 term_esc_state
= IS_NORM
;
370 static void term_insert_char(int ch
)
372 if (term_cmd_buf_index
< TERM_CMD_BUF_SIZE
) {
373 memmove(term_cmd_buf
+ term_cmd_buf_index
+ 1,
374 term_cmd_buf
+ term_cmd_buf_index
,
375 term_cmd_buf_size
- term_cmd_buf_index
);
376 term_cmd_buf
[term_cmd_buf_index
] = ch
;
378 term_printf("\033[@%c", ch
);
379 term_cmd_buf_index
++;
384 static void term_backward_char(void)
386 if (term_cmd_buf_index
> 0) {
387 term_cmd_buf_index
--;
388 term_printf("\033[D");
393 static void term_forward_char(void)
395 if (term_cmd_buf_index
< term_cmd_buf_size
) {
396 term_cmd_buf_index
++;
397 term_printf("\033[C");
402 static void term_delete_char(void)
404 if (term_cmd_buf_index
< term_cmd_buf_size
) {
405 memmove(term_cmd_buf
+ term_cmd_buf_index
,
406 term_cmd_buf
+ term_cmd_buf_index
+ 1,
407 term_cmd_buf_size
- term_cmd_buf_index
- 1);
408 term_printf("\033[P");
414 static void term_backspace(void)
416 if (term_cmd_buf_index
> 0) {
417 term_backward_char();
422 static void term_bol(void)
424 while (term_cmd_buf_index
> 0)
425 term_backward_char();
428 static void term_eol(void)
430 while (term_cmd_buf_index
< term_cmd_buf_size
)
434 /* return true if command handled */
435 static void term_handle_byte(int ch
)
437 switch(term_esc_state
) {
448 term_cmd_buf
[term_cmd_buf_size
] = '\0';
450 term_handle_command(term_cmd_buf
);
454 term_esc_state
= IS_ESC
;
462 term_insert_char(ch
);
469 term_esc_state
= IS_CSI
;
472 term_esc_state
= IS_NORM
;
478 term_backward_char();
484 term_esc_param
= term_esc_param
* 10 + (ch
- '0');
487 switch(term_esc_param
) {
502 term_esc_state
= IS_NORM
;
508 /*************************************************************/
509 /* serial console support */
511 #define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
513 static int term_got_escape
, term_command
;
515 void term_print_help(void)
518 "C-a h print this help\n"
519 "C-a x exit emulatior\n"
520 "C-a s save disk data back to file (if -snapshot)\n"
521 "C-a b send break (magic sysrq)\n"
522 "C-a c switch between console and monitor\n"
527 /* called when a char is received */
528 static void term_received_byte(int ch
)
530 if (!serial_console
) {
531 /* if no serial console, handle every command */
532 term_handle_byte(ch
);
534 if (term_got_escape
) {
546 for (i
= 0; i
< MAX_DISKS
; i
++) {
548 bdrv_commit(bs_table
[i
]);
554 serial_receive_break(serial_console
);
567 } else if (ch
== TERM_ESCAPE
) {
572 term_handle_byte(ch
);
575 serial_receive_byte(serial_console
, ch
);
581 static int term_can_read(void *opaque
)
583 if (serial_console
) {
584 return serial_can_receive(serial_console
);
590 static void term_read(void *opaque
, const uint8_t *buf
, int size
)
593 for(i
= 0; i
< size
; i
++)
594 term_received_byte(buf
[i
]);
597 void monitor_init(void)
599 if (!serial_console
) {
600 term_printf("QEMU %s monitor - type 'help' for more information\n",
604 add_fd_read_handler(0, term_can_read
, term_read
, NULL
);