From b9a0840307843ba0bfa85af95f8ade081c0fed5b Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Mon, 17 Sep 2018 11:27:38 +0200 Subject: [PATCH] tty, win: fix read stop for raw mode New Windows version requires `EventType` to be set to something meaningful, otherwise WriteConsoleInputW() will fail with `ERROR_INVALID_PARAMETER`. This sets it to `FOCUS_EVENT` which is ignored by `uv_process_tty_read_raw_req()`. Fixes: https://github.com/nodejs/node/issues/21773 PR-URL: https://github.com/libuv/libuv/pull/1989 Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen Reviewed-By: Santiago Gimeno Reviewed-By: Colin Ihrig Reviewed-By: Jameson Nash --- src/win/tty.c | 1 + test/test-list.h | 2 ++ test/test-tty.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/win/tty.c b/src/win/tty.c index 7045b115..dacb8a82 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -1033,6 +1033,7 @@ int uv_tty_read_stop(uv_tty_t* handle) { /* Cancel raw read. Write some bullshit event to force the console wait to * return. */ memset(&record, 0, sizeof record); + record.EventType = FOCUS_EVENT; if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) { return GetLastError(); } diff --git a/test/test-list.h b/test/test-list.h index b501722d..ee4c81cf 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -50,6 +50,7 @@ TEST_DECLARE (tty) TEST_DECLARE (tty_raw) TEST_DECLARE (tty_empty_write) TEST_DECLARE (tty_large_write) +TEST_DECLARE (tty_raw_cancel) #endif TEST_DECLARE (tty_file) TEST_DECLARE (tty_pty) @@ -480,6 +481,7 @@ TASK_LIST_START TEST_ENTRY (tty_raw) TEST_ENTRY (tty_empty_write) TEST_ENTRY (tty_large_write) + TEST_ENTRY (tty_raw_cancel) #endif TEST_ENTRY (tty_file) TEST_ENTRY (tty_pty) diff --git a/test/test-tty.c b/test/test-tty.c index 3bbdfad7..979a6ec3 100644 --- a/test/test-tty.c +++ b/test/test-tty.c @@ -310,6 +310,41 @@ TEST_IMPL(tty_large_write) { MAKE_VALGRIND_HAPPY(); return 0; } + +TEST_IMPL(tty_raw_cancel) { + int r; + int ttyin_fd; + uv_tty_t tty_in; + uv_loop_t* loop; + HANDLE handle; + + loop = uv_default_loop(); + /* Make sure we have an FD that refers to a tty */ + handle = CreateFileA("conin$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyin_fd = _open_osfhandle((intptr_t) handle, 0); + ASSERT(ttyin_fd >= 0); + ASSERT(UV_TTY == uv_guess_handle(ttyin_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */ + ASSERT(r == 0); + r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW); + ASSERT(r == 0); + r = uv_read_start((uv_stream_t*)&tty_in, tty_raw_alloc, tty_raw_read); + ASSERT(r == 0); + + r = uv_read_stop((uv_stream_t*) &tty_in); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} #endif