diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2016-12-12 17:49:52 +0300 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2017-01-31 23:31:21 +0400 |
commit | 0e58f1777794424c64711ab5f96c5887fc712d93 (patch) | |
tree | c49a17e24cbbe416a3240c028f15fb75cefb3918 /chardev/char.c | |
parent | 503ebefe0a2d09405a2b562d265211dd16d0448a (diff) |
char: move win-stdio into its own file
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Eric Blake <eblake@redhat.com>
Diffstat (limited to 'chardev/char.c')
-rw-r--r-- | chardev/char.c | 231 |
1 files changed, 2 insertions, 229 deletions
diff --git a/chardev/char.c b/chardev/char.c index b80fcae028..8393bb0294 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -90,6 +90,7 @@ #include "char-io.h" #ifdef _WIN32 #include "char-win.h" +#include "char-win-stdio.h" #endif #define TCP_MAX_FDS 16 @@ -1474,19 +1475,6 @@ static void qemu_chr_open_pp_fd(Chardev *chr, #define HAVE_CHARDEV_SERIAL 1 -typedef struct { - Chardev parent; - HANDLE hStdIn; - HANDLE hInputReadyEvent; - HANDLE hInputDoneEvent; - HANDLE hInputThread; - uint8_t win_stdio_buf; -} WinStdioChardev; - -#define TYPE_CHARDEV_WIN_STDIO "chardev-win-stdio" -#define WIN_STDIO_CHARDEV(obj) \ - OBJECT_CHECK(WinStdioChardev, (obj), TYPE_CHARDEV_WIN_STDIO) - #define MAXCONNECT 1 #define NTIMEOUT 5000 @@ -1588,215 +1576,6 @@ static const TypeInfo char_console_type_info = { .class_init = char_console_class_init, }; -static int win_stdio_write(Chardev *chr, const uint8_t *buf, int len) -{ - HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD dwSize; - int len1; - - len1 = len; - - while (len1 > 0) { - if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) { - break; - } - buf += dwSize; - len1 -= dwSize; - } - - return len - len1; -} - -static void win_stdio_wait_func(void *opaque) -{ - Chardev *chr = CHARDEV(opaque); - WinStdioChardev *stdio = WIN_STDIO_CHARDEV(opaque); - INPUT_RECORD buf[4]; - int ret; - DWORD dwSize; - int i; - - ret = ReadConsoleInput(stdio->hStdIn, buf, ARRAY_SIZE(buf), &dwSize); - - if (!ret) { - /* Avoid error storm */ - qemu_del_wait_object(stdio->hStdIn, NULL, NULL); - return; - } - - for (i = 0; i < dwSize; i++) { - KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent; - - if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) { - int j; - if (kev->uChar.AsciiChar != 0) { - for (j = 0; j < kev->wRepeatCount; j++) { - if (qemu_chr_be_can_write(chr)) { - uint8_t c = kev->uChar.AsciiChar; - qemu_chr_be_write(chr, &c, 1); - } - } - } - } - } -} - -static DWORD WINAPI win_stdio_thread(LPVOID param) -{ - WinStdioChardev *stdio = WIN_STDIO_CHARDEV(param); - int ret; - DWORD dwSize; - - while (1) { - - /* Wait for one byte */ - ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL); - - /* Exit in case of error, continue if nothing read */ - if (!ret) { - break; - } - if (!dwSize) { - continue; - } - - /* Some terminal emulator returns \r\n for Enter, just pass \n */ - if (stdio->win_stdio_buf == '\r') { - continue; - } - - /* Signal the main thread and wait until the byte was eaten */ - if (!SetEvent(stdio->hInputReadyEvent)) { - break; - } - if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE) - != WAIT_OBJECT_0) { - break; - } - } - - qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); - return 0; -} - -static void win_stdio_thread_wait_func(void *opaque) -{ - Chardev *chr = CHARDEV(opaque); - WinStdioChardev *stdio = WIN_STDIO_CHARDEV(opaque); - - if (qemu_chr_be_can_write(chr)) { - qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1); - } - - SetEvent(stdio->hInputDoneEvent); -} - -static void qemu_chr_set_echo_win_stdio(Chardev *chr, bool echo) -{ - WinStdioChardev *stdio = WIN_STDIO_CHARDEV(chr); - DWORD dwMode = 0; - - GetConsoleMode(stdio->hStdIn, &dwMode); - - if (echo) { - SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT); - } else { - SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT); - } -} - -static void char_win_stdio_finalize(Object *obj) -{ - WinStdioChardev *stdio = WIN_STDIO_CHARDEV(obj); - - if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) { - CloseHandle(stdio->hInputReadyEvent); - } - if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) { - CloseHandle(stdio->hInputDoneEvent); - } - if (stdio->hInputThread != INVALID_HANDLE_VALUE) { - TerminateThread(stdio->hInputThread, 0); - } -} - -static const TypeInfo char_win_stdio_type_info = { - .name = TYPE_CHARDEV_WIN_STDIO, - .parent = TYPE_CHARDEV, - .instance_size = sizeof(WinStdioChardev), - .instance_finalize = char_win_stdio_finalize, - .abstract = true, -}; - -static void qemu_chr_open_stdio(Chardev *chr, - ChardevBackend *backend, - bool *be_opened, - Error **errp) -{ - WinStdioChardev *stdio = WIN_STDIO_CHARDEV(chr); - DWORD dwMode; - int is_console = 0; - - stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); - if (stdio->hStdIn == INVALID_HANDLE_VALUE) { - error_setg(errp, "cannot open stdio: invalid handle"); - return; - } - - is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; - - if (is_console) { - if (qemu_add_wait_object(stdio->hStdIn, - win_stdio_wait_func, chr)) { - error_setg(errp, "qemu_add_wait_object: failed"); - goto err1; - } - } else { - DWORD dwId; - - stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE - || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) { - error_setg(errp, "cannot create event"); - goto err2; - } - if (qemu_add_wait_object(stdio->hInputReadyEvent, - win_stdio_thread_wait_func, chr)) { - error_setg(errp, "qemu_add_wait_object: failed"); - goto err2; - } - stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, - chr, 0, &dwId); - - if (stdio->hInputThread == INVALID_HANDLE_VALUE) { - error_setg(errp, "cannot create stdio thread"); - goto err3; - } - } - - dwMode |= ENABLE_LINE_INPUT; - - if (is_console) { - /* set the terminal in raw mode */ - /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */ - dwMode |= ENABLE_PROCESSED_INPUT; - } - - SetConsoleMode(stdio->hStdIn, dwMode); - - qemu_chr_set_echo_win_stdio(chr, false); - - return; - -err3: - qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); -err2: - CloseHandle(stdio->hInputReadyEvent); - CloseHandle(stdio->hInputDoneEvent); -err1: - qemu_del_wait_object(stdio->hStdIn, NULL, NULL); -} #endif /* !_WIN32 */ /***********************************************************/ @@ -2785,11 +2564,8 @@ static void char_stdio_class_init(ObjectClass *oc, void *data) ChardevClass *cc = CHARDEV_CLASS(oc); cc->parse = qemu_chr_parse_stdio; +#ifndef _WIN32 cc->open = qemu_chr_open_stdio; -#ifdef _WIN32 - cc->chr_write = win_stdio_write; - cc->chr_set_echo = qemu_chr_set_echo_win_stdio; -#else cc->chr_set_echo = qemu_chr_set_echo_stdio; #endif } @@ -3955,9 +3731,6 @@ void qemu_chr_cleanup(void) static void register_types(void) { type_register_static(&char_type_info); -#ifdef _WIN32 - type_register_static(&char_win_stdio_type_info); -#endif type_register_static(&char_socket_type_info); type_register_static(&char_udp_type_info); type_register_static(&char_file_type_info); |