/* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ qemu_chr_fe_write_all(&d->chr, (uint8_t *)buf1, strlen(buf1)); d->linestart = 0; } ret += qemu_chr_fe_write(&d->chr, buf + i, 1); if (buf[i] == '\n') { d->linestart = 1; } } } return ret; } static const char * const mux_help[] = { "% h print this help\n\r", "% x exit emulator\n\r", "% s save disk data back to file (if -snapshot)\n\r", "% t toggle console timestamps\n\r", "% b send break (magic sysrq)\n\r", "% c switch between console and monitor\n\r", "% % sends %\n\r", NULL }; int term_escape_char = 0x01; /* ctrl-a is used for escape */ static void mux_print_help(Chardev *chr) { int i, j; char ebuf[15] = "Escape-Char"; char cbuf[50] = "\n\r"; if (term_escape_char > 0 && term_escape_char < 26) { snprintf(cbuf, sizeof(cbuf), "\n\r"); snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a'); } else { snprintf(cbuf, sizeof(cbuf), "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", term_escape_char); } /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ qemu_chr_write_all(chr, (uint8_t *)cbuf, strlen(cbuf)); for (i = 0; mux_help[i] != NULL; i++) { for (j = 0; mux_help[i][j] != '\0'; j++) { if (mux_help[i][j] == '%') { qemu_chr_write_all(chr, (uint8_t *)ebuf, strlen(ebuf)); } else { qemu_chr_write_all(chr, (uint8_t *)&mux_help[i][j], 1); } } } }
static void char_console_test_subprocess(void) { QemuOpts *opts; Chardev *chr; opts = qemu_opts_create(qemu_find_opts("chardev"), "console-label", 1, &error_abort); qemu_opt_set(opts, "backend", "console", &error_abort); chr = qemu_chr_new_from_opts(opts, NULL); g_assert_nonnull(chr); qemu_chr_write_all(chr, (const uint8_t *)"CONSOLE", 7); qemu_opts_del(opts); object_unparent(OBJECT(chr)); }
static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch) { if (d->term_got_escape) { d->term_got_escape = 0; if (ch == term_escape_char) { goto send_char; } switch (ch) { case '?': case 'h': mux_print_help(chr); break; case 'x': { const char *term = "QEMU: Terminated\n\r"; qemu_chr_write_all(chr, (uint8_t *)term, strlen(term)); exit(0); break; } case 's': blk_commit_all(); break; case 'b': qemu_chr_be_event(chr, CHR_EVENT_BREAK); break; case 'c': assert(d->mux_cnt > 0); /* handler registered with first fe */ /* Switch to the next registered device */ mux_set_focus(chr, (d->focus + 1) % d->mux_cnt); break; case 't': d->timestamps = !d->timestamps; d->timestamps_start = -1; d->linestart = 0; break; } } else if (ch == term_escape_char) { d->term_got_escape = 1; } else { send_char: return 1; } return 0; }