[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 16/22] Serial ports replay and stdio monitor for
From: |
Pavel Dovgaluk |
Subject: |
[Qemu-devel] [RFC PATCH 16/22] Serial ports replay and stdio monitor for Win32 |
Date: |
Tue, 1 Jul 2014 15:29:45 +0400 |
These files include the following changes:
- Record/replay functions for COM ports added by -serial command-line option.
- Implementation of stdio monitor for Win32.
Signed-off-by: Pavel Dovgalyuk <address@hidden>
---
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index c8b15f9..5e13fab
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -86,6 +86,7 @@ struct CharDriverState {
guint fd_in_tag;
guint fd_hup_tag;
QemuOpts *opts;
+ bool replay;
QTAILQ_ENTRY(CharDriverState) next;
};
@@ -125,6 +126,8 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
*/
CharDriverState *qemu_chr_new(const char *label, const char *filename,
void (*init)(struct CharDriverState *s));
+CharDriverState *qemu_chr_new_replay(const char *label, const char *filename,
+ void (*init)(struct CharDriverState *s));
/**
* @qemu_chr_delete:
@@ -320,6 +323,7 @@ int qemu_chr_be_can_write(CharDriverState *s);
* @len the number of bytes to receive from the front end
*/
void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
+void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len);
/**
diff --git a/qemu-char.c b/qemu-char.c
index 51917de..4627eef
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -81,6 +81,7 @@
#include "qemu/sockets.h"
#include "ui/qemu-spice.h"
+#include "replay/replay.h"
#define READ_BUF_LEN 4096
#define READ_RETRIES 10
@@ -126,6 +127,9 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t
*buf, int len)
qemu_mutex_lock(&s->chr_write_lock);
ret = s->chr_write(s, buf, len);
+ if (s->replay) {
+ replay_data_int(&ret);
+ }
qemu_mutex_unlock(&s->chr_write_lock);
return ret;
}
@@ -195,9 +199,18 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf,
int len)
int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
{
- if (!s->chr_ioctl)
- return -ENOTSUP;
- return s->chr_ioctl(s, cmd, arg);
+ int res;
+ if (!s->chr_ioctl) {
+ res = -ENOTSUP;
+ } else {
+ res = s->chr_ioctl(s, cmd, arg);
+ if (s->replay) {
+ fprintf(stderr, "Replay: ioctl is not supported for serial devices
yet\n");
+ exit(1);
+ }
+ }
+
+ return res;
}
int qemu_chr_be_can_write(CharDriverState *s)
@@ -207,17 +220,34 @@ int qemu_chr_be_can_write(CharDriverState *s)
return s->chr_can_read(s->handler_opaque);
}
-void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
+void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len)
{
if (s->chr_read) {
s->chr_read(s->handler_opaque, buf, len);
}
}
+void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
+{
+ if (s->replay) {
+ if (replay_mode == REPLAY_PLAY) {
+ fprintf(stderr, "Replay: calling qemu_chr_be_write in play
mode\n");
+ exit(1);
+ }
+ replay_chr_be_write(s, buf, len);
+ } else {
+ qemu_chr_be_write_impl(s, buf, len);
+ }
+}
+
int qemu_chr_fe_get_msgfd(CharDriverState *s)
{
int fd;
- return (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1;
+ int res = (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1;
+ if (s->replay) {
+ replay_data_int(&res);
+ }
+ return res;
}
int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int len)
@@ -1923,6 +1953,8 @@ static int win_chr_pipe_poll(void *opaque)
if (size > 0) {
s->len = size;
win_chr_read_poll(chr);
+ if (s->max_size == 0)
+ return 0;
win_chr_read(chr);
return 1;
}
@@ -2034,19 +2066,41 @@ static int win_stdio_write(CharDriverState *chr, const
uint8_t *buf, int
len)
{
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD dwSize;
- int len1;
+ int ret = 0;
+ CONSOLE_SCREEN_BUFFER_INFO info;
- len1 = len;
-
- while (len1 > 0) {
- if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
- break;
+ while (len > 0) {
+ if (len > 2 && buf[0] == '\033' && buf[1] == '[') {
+ switch (buf[2]) {
+ case 'D':
+ if (!WriteFile(hStdOut, "\b", 1, &dwSize, NULL)) {
+ return ret;
+ }
+ break;
+ case 'K':
+ if (!GetConsoleScreenBufferInfo(hStdOut, &info)) {
+ return ret;
+ }
+ if (!FillConsoleOutputCharacter(hStdOut, ' ',
+ info.dwSize.X - info.dwCursorPosition.X,
+ info.dwCursorPosition, &dwSize)) {
+ return ret;
+ }
+ break;
+ }
+ dwSize = 3;
+ } else {
+ if (!WriteFile(hStdOut, buf, 1, &dwSize, NULL)) {
+ return ret;
+ }
}
- buf += dwSize;
- len1 -= dwSize;
+
+ buf += dwSize;
+ len -= dwSize;
+ ret += dwSize;
}
- return len - len1;
+ return ret;
}
static void win_stdio_wait_func(void *opaque)
@@ -2170,19 +2224,24 @@ static CharDriverState
*qemu_chr_open_stdio(ChardevStdio *opts)
{
CharDriverState *chr;
WinStdioCharState *stdio;
+ HANDLE hStdOut;
DWORD dwMode;
+ DWORD dwOutMode;
int is_console = 0;
chr = qemu_chr_alloc();
stdio = g_malloc0(sizeof(WinStdioCharState));
stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
- if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
+ hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (stdio->hStdIn == INVALID_HANDLE_VALUE
+ || hStdOut == INVALID_HANDLE_VALUE) {
fprintf(stderr, "cannot open stdio: invalid handle\n");
exit(1);
}
is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
+ GetConsoleMode(hStdOut, &dwOutMode);
chr->opaque = stdio;
chr->chr_write = win_stdio_write;
@@ -2219,9 +2278,11 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio
*opts)
/* set the terminal in raw mode */
/* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
dwMode |= ENABLE_PROCESSED_INPUT;
+ dwOutMode |= ENABLE_PROCESSED_OUTPUT;
}
SetConsoleMode(stdio->hStdIn, dwMode);
+ SetConsoleMode(hStdOut, dwOutMode);
chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
qemu_chr_fe_set_echo(chr, false);
@@ -3615,6 +3676,18 @@ CharDriverState *qemu_chr_new(const char *label, const
char *filename, void
(*in
return chr;
}
+CharDriverState *qemu_chr_new_replay(const char *label, const char *filename,
void (*init)(struct
CharDriverState *s))
+{
+ if (replay_mode == REPLAY_PLAY && (strcmp(filename, "null") &&
strcmp(filename, "vc:80Cx24C")))
{
+ fprintf(stderr, "Only \"-serial null\" can be used with replay\n");
+ exit(1);
+ }
+ CharDriverState *chr = qemu_chr_new(label, filename, init);
+ if (strcmp(filename, "vc:80Cx24C"))
+ replay_register_char_driver(chr);
+ return chr;
+}
+
void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
{
if (chr->chr_set_echo) {
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [RFC PATCH 16/22] Serial ports replay and stdio monitor for Win32,
Pavel Dovgaluk <=