diff options
Diffstat (limited to 'qemu-io.c')
-rw-r--r-- | qemu-io.c | 119 |
1 files changed, 70 insertions, 49 deletions
@@ -18,6 +18,7 @@ #include "qemu/main-loop.h" #include "qemu/option.h" #include "qemu/config-file.h" +#include "qemu/readline.h" #include "block/block_int.h" #include "trace/control.h" @@ -32,6 +33,8 @@ extern int qemuio_misalign; static int ncmdline; static char **cmdline; +static ReadLineState *readline_state; + static int close_f(BlockDriverState *bs, int argc, char **argv) { bdrv_unref(bs); @@ -56,7 +59,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts) } if (growable) { - if (bdrv_file_open(&qemuio_bs, name, opts, flags, &local_err)) { + if (bdrv_file_open(&qemuio_bs, name, NULL, opts, flags, &local_err)) { fprintf(stderr, "%s: can't open device %s: %s\n", progname, name, error_get_pretty(local_err)); error_free(local_err); @@ -160,11 +163,13 @@ static int open_f(BlockDriverState *bs, int argc, char **argv) flags |= BDRV_O_RDWR; } - if (optind != argc - 1) { + if (optind == argc - 1) { + return openfile(argv[optind], flags, growable, opts); + } else if (optind == argc) { + return openfile(NULL, flags, growable, opts); + } else { return qemuio_command_usage(&open_cmd); } - - return openfile(argv[optind], flags, growable, opts); } static int quit_f(BlockDriverState *bs, int argc, char **argv) @@ -203,14 +208,6 @@ static void usage(const char *name) name); } - -#if defined(ENABLE_READLINE) -# include <readline/history.h> -# include <readline/readline.h> -#elif defined(ENABLE_EDITLINE) -# include <histedit.h> -#endif - static char *get_prompt(void) { static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ]; @@ -222,52 +219,53 @@ static char *get_prompt(void) return prompt; } -#if defined(ENABLE_READLINE) -static char *fetchline(void) +static void readline_printf_func(void *opaque, const char *fmt, ...) { - char *line = readline(get_prompt()); - if (line && *line) { - add_history(line); - } - return line; + va_list ap; + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); } -#elif defined(ENABLE_EDITLINE) -static char *el_get_prompt(EditLine *e) + +static void readline_flush_func(void *opaque) { - return get_prompt(); + fflush(stdout); } -static char *fetchline(void) +static void readline_func(void *opaque, const char *str, void *readline_opaque) { - static EditLine *el; - static History *hist; - HistEvent hevent; - char *line; - int count; - - if (!el) { - hist = history_init(); - history(hist, &hevent, H_SETSIZE, 100); - el = el_init(progname, stdin, stdout, stderr); - el_source(el, NULL); - el_set(el, EL_SIGNAL, 1); - el_set(el, EL_PROMPT, el_get_prompt); - el_set(el, EL_HIST, history, (const char *)hist); - } - line = strdup(el_gets(el, &count)); - if (line) { - if (count > 0) { - line[count-1] = '\0'; - } - if (*line) { - history(hist, &hevent, H_ENTER, line); + char **line = readline_opaque; + *line = g_strdup(str); +} + +static void completion_match(const char *cmd, void *opaque) +{ + readline_add_completion(readline_state, cmd); +} + +static void readline_completion_func(void *opaque, const char *str) +{ + readline_set_completion_index(readline_state, strlen(str)); + qemuio_complete_command(str, completion_match, NULL); +} + +static char *fetchline_readline(void) +{ + char *line = NULL; + + readline_start(readline_state, get_prompt(), 0, readline_func, &line); + while (!line) { + int ch = getchar(); + if (ch == EOF) { + break; } + readline_handle_byte(readline_state, ch); } return line; } -#else -# define MAXREADLINESZ 1024 -static char *fetchline(void) + +#define MAXREADLINESZ 1024 +static char *fetchline_fgets(void) { char *p, *line = g_malloc(MAXREADLINESZ); @@ -283,7 +281,15 @@ static char *fetchline(void) return line; } -#endif + +static char *fetchline(void) +{ + if (readline_state) { + return fetchline_readline(); + } else { + return fetchline_fgets(); + } +} static void prep_fetchline(void *opaque) { @@ -339,6 +345,11 @@ static void add_user_command(char *optarg) cmdline[ncmdline-1] = optarg; } +static void reenable_tty_echo(void) +{ + qemu_set_tty_echo(STDIN_FILENO, true); +} + int main(int argc, char **argv) { int readonly = 0; @@ -435,6 +446,15 @@ int main(int argc, char **argv) qemuio_add_command(&open_cmd); qemuio_add_command(&close_cmd); + if (isatty(STDIN_FILENO)) { + readline_state = readline_init(readline_printf_func, + readline_flush_func, + NULL, + readline_completion_func); + qemu_set_tty_echo(STDIN_FILENO, false); + atexit(reenable_tty_echo); + } + /* open the device */ if (!readonly) { flags |= BDRV_O_RDWR; @@ -453,5 +473,6 @@ int main(int argc, char **argv) if (qemuio_bs) { bdrv_unref(qemuio_bs); } + g_free(readline_state); return 0; } |