1
+ diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
2
+ index 02397dd0fdd4..3971dc869c99 100644
3
+ --- a/deps/uv/include/uv.h
4
+ +++ b/deps/uv/include/uv.h
5
+ @@ -770,10 +770,15 @@ struct uv_tty_s {
6
+ typedef enum {
7
+ /* Initial/normal terminal mode */
8
+ UV_TTY_MODE_NORMAL,
9
+ - /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
10
+ + /*
11
+ + * Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled).
12
+ + * May become equivalent to UV_TTY_MODE_RAW_VT in future libuv versions.
13
+ + */
14
+ UV_TTY_MODE_RAW,
15
+ /* Binary-safe I/O mode for IPC (Unix-only) */
16
+ - UV_TTY_MODE_IO
17
+ + UV_TTY_MODE_IO,
18
+ + /* Raw input mode. On Windows ENABLE_VIRTUAL_TERMINAL_INPUT is also set. */
19
+ + UV_TTY_MODE_RAW_VT
20
+ } uv_tty_mode_t;
21
+
22
+ typedef enum {
23
+ diff --git a/deps/uv/include/uv/win.h b/deps/uv/include/uv/win.h
24
+ index 6f8c47298e40..2b29325c520c 100644
25
+ --- a/deps/uv/include/uv/win.h
26
+ +++ b/deps/uv/include/uv/win.h
27
+ @@ -507,8 +507,11 @@ typedef struct {
28
+ union { \
29
+ struct { \
30
+ /* Used for readable TTY handles */ \
31
+ - /* TODO: remove me in v2.x. */ \
32
+ - HANDLE unused_; \
33
+ + union { \
34
+ + /* TODO: remove me in v2.x. */ \
35
+ + HANDLE unused_; \
36
+ + int mode; \
37
+ + } mode; \
38
+ uv_buf_t read_line_buffer; \
39
+ HANDLE read_raw_wait; \
40
+ /* Fields used for translating win keystrokes into vt100 characters */ \
41
+ diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
42
+ index d099bdb3b677..19aabc84935f 100644
43
+ --- a/deps/uv/src/unix/tty.c
44
+ +++ b/deps/uv/src/unix/tty.c
45
+ @@ -284,6 +284,11 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
46
+ int fd;
47
+ int rc;
48
+
49
+ + if (uv__is_raw_tty_mode(mode)) {
50
+ + /* There is only a single raw TTY mode on UNIX. */
51
+ + mode = UV_TTY_MODE_RAW;
52
+ + }
53
+ +
54
+ if (tty->mode == (int) mode)
55
+ return 0;
56
+
57
+ @@ -324,6 +329,8 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
58
+ case UV_TTY_MODE_IO:
59
+ uv__tty_make_raw(&tmp);
60
+ break;
61
+ + default:
62
+ + UNREACHABLE();
63
+ }
64
+
65
+ /* Apply changes after draining */
66
+ diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h
67
+ index cd57e5a35153..6ba8399bf873 100644
68
+ --- a/deps/uv/src/uv-common.h
69
+ +++ b/deps/uv/src/uv-common.h
70
+ @@ -125,7 +125,7 @@ enum {
71
+
72
+ /* Only used by uv_tty_t handles. */
73
+ UV_HANDLE_TTY_READABLE = 0x01000000,
74
+ - UV_HANDLE_TTY_RAW = 0x02000000,
75
+ + UV_HANDLE_UNUSED0 = 0x02000000,
76
+ UV_HANDLE_TTY_SAVED_POSITION = 0x04000000,
77
+ UV_HANDLE_TTY_SAVED_ATTRIBUTES = 0x08000000,
78
+
79
+ @@ -140,6 +140,10 @@ enum {
80
+ UV_HANDLE_REAP = 0x10000000
81
+ };
82
+
83
+ + static inline int uv__is_raw_tty_mode(uv_tty_mode_t m) {
84
+ + return m == UV_TTY_MODE_RAW || m == UV_TTY_MODE_RAW_VT;
85
+ + }
86
+ +
87
+ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
88
+
89
+ void uv__loop_close(uv_loop_t* loop);
1
90
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
2
- index 7e1f15544b17..37bc2c4ace57 100644
91
+ index 7e1f15544b17..26b9d0deced5 100644
3
92
--- a/deps/uv/src/win/tty.c
4
93
+++ b/deps/uv/src/win/tty.c
5
94
@@ -58,6 +58,9 @@
@@ -9,38 +98,199 @@ index 7e1f15544b17..37bc2c4ace57 100644
9
98
+ #ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
10
99
+ #define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
11
100
+ #endif
12
-
101
+
13
102
#define CURSOR_SIZE_SMALL 25
14
103
#define CURSOR_SIZE_LARGE 100
15
- @@ -344,6 +347,7 @@ static void uv__tty_capture_initial_style(
16
-
104
+ @@ -119,7 +122,10 @@ static int uv_tty_virtual_width = -1;
105
+ * handle signalling SIGWINCH
106
+ */
107
+
108
+ - static HANDLE uv__tty_console_handle = INVALID_HANDLE_VALUE;
109
+ + static HANDLE uv__tty_console_handle_out = INVALID_HANDLE_VALUE;
110
+ + static HANDLE uv__tty_console_handle_in = INVALID_HANDLE_VALUE;
111
+ + static DWORD uv__tty_console_in_original_mode = (DWORD)-1;
112
+ + static volatile LONG uv__tty_console_in_need_mode_reset = 0;
113
+ static int uv__tty_console_height = -1;
114
+ static int uv__tty_console_width = -1;
115
+ static HANDLE uv__tty_console_resized = INVALID_HANDLE_VALUE;
116
+ @@ -159,19 +165,21 @@ static uv_tty_vtermstate_t uv__vterm_state = UV_TTY_UNSUPPORTED;
117
+ static void uv__determine_vterm_state(HANDLE handle);
118
+
119
+ void uv__console_init(void) {
120
+ + DWORD dwMode;
121
+ +
122
+ if (uv_sem_init(&uv_tty_output_lock, 1))
123
+ abort();
124
+ - uv__tty_console_handle = CreateFileW(L"CONOUT$",
125
+ - GENERIC_READ | GENERIC_WRITE,
126
+ - FILE_SHARE_WRITE,
127
+ - 0,
128
+ - OPEN_EXISTING,
129
+ - 0,
130
+ - 0);
131
+ - if (uv__tty_console_handle != INVALID_HANDLE_VALUE) {
132
+ + uv__tty_console_handle_out = CreateFileW(L"CONOUT$",
133
+ + GENERIC_READ | GENERIC_WRITE,
134
+ + FILE_SHARE_WRITE,
135
+ + 0,
136
+ + OPEN_EXISTING,
137
+ + 0,
138
+ + 0);
139
+ + if (uv__tty_console_handle_out != INVALID_HANDLE_VALUE) {
140
+ CONSOLE_SCREEN_BUFFER_INFO sb_info;
141
+ uv_mutex_init(&uv__tty_console_resize_mutex);
142
+ - if (GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) {
143
+ + if (GetConsoleScreenBufferInfo(uv__tty_console_handle_out, &sb_info)) {
144
+ uv__tty_console_width = sb_info.dwSize.X;
145
+ uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
146
+ }
147
+ @@ -179,6 +187,18 @@ void uv__console_init(void) {
148
+ NULL,
149
+ WT_EXECUTELONGFUNCTION);
150
+ }
151
+ + uv__tty_console_handle_in = CreateFileW(L"CONIN$",
152
+ + GENERIC_READ | GENERIC_WRITE,
153
+ + FILE_SHARE_READ,
154
+ + 0,
155
+ + OPEN_EXISTING,
156
+ + 0,
157
+ + 0);
158
+ + if (uv__tty_console_handle_in != INVALID_HANDLE_VALUE) {
159
+ + if (GetConsoleMode(uv__tty_console_handle_in, &dwMode)) {
160
+ + uv__tty_console_in_original_mode = dwMode;
161
+ + }
162
+ + }
163
+ }
164
+
165
+
166
+ @@ -253,7 +273,9 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int unused) {
167
+ /* Initialize TTY input specific fields. */
168
+ tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
169
+ /* TODO: remove me in v2.x. */
170
+ - tty->tty.rd.unused_ = NULL;
171
+ + tty->tty.rd.mode.unused_ = NULL;
172
+ + /* Partially overwrites unused_ again. */
173
+ + tty->tty.rd.mode.mode = 0;
174
+ tty->tty.rd.read_line_buffer = uv_null_buf_;
175
+ tty->tty.rd.read_raw_wait = NULL;
176
+
177
+ @@ -344,6 +366,7 @@ static void uv__tty_capture_initial_style(
178
+
17
179
int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
18
180
DWORD flags;
19
181
+ DWORD try_set_flags;
20
182
unsigned char was_reading;
21
183
uv_alloc_cb alloc_cb;
22
184
uv_read_cb read_cb;
23
- @@ -360,9 +364,11 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
185
+ @@ -353,14 +376,19 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
186
+ return UV_EINVAL;
187
+ }
188
+
189
+ - if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) {
190
+ + if ((int)mode == tty->tty.rd.mode.mode) {
191
+ return 0;
192
+ }
193
+
194
+ + try_set_flags = 0;
24
195
switch (mode) {
25
196
case UV_TTY_MODE_NORMAL:
26
197
flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
27
- + try_set_flags = 0;
28
198
break;
199
+ + case UV_TTY_MODE_RAW_VT:
200
+ + try_set_flags = ENABLE_VIRTUAL_TERMINAL_INPUT;
201
+ + InterlockedExchange(&uv__tty_console_in_need_mode_reset, 1);
202
+ + /* fallthrough */
29
203
case UV_TTY_MODE_RAW:
30
204
flags = ENABLE_WINDOW_INPUT;
31
- + try_set_flags = ENABLE_VIRTUAL_TERMINAL_INPUT;
32
205
break;
33
- case UV_TTY_MODE_IO:
34
- return UV_ENOTSUP;
35
- @@ -386,7 +392,10 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
206
+ @@ -386,16 +414,16 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
36
207
}
37
-
208
+
38
209
uv_sem_wait(&uv_tty_output_lock);
39
210
- if (!SetConsoleMode(tty->handle, flags)) {
40
- + if (
41
- + !SetConsoleMode(tty->handle, flags | try_set_flags) &&
42
- + !SetConsoleMode(tty->handle, flags)
43
- + ) {
211
+ + if (!SetConsoleMode(tty->handle, flags | try_set_flags) &&
212
+ + !SetConsoleMode(tty->handle, flags)) {
44
213
err = uv_translate_sys_error(GetLastError());
45
214
uv_sem_post(&uv_tty_output_lock);
46
215
return err;
216
+ }
217
+ uv_sem_post(&uv_tty_output_lock);
218
+
219
+ - /* Update flag. */
220
+ - tty->flags &= ~UV_HANDLE_TTY_RAW;
221
+ - tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0;
222
+ + /* Update mode. */
223
+ + tty->tty.rd.mode.mode = mode;
224
+
225
+ /* If we just stopped reading, restart. */
226
+ if (was_reading) {
227
+ @@ -615,7 +643,7 @@ static void uv__tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
228
+
229
+
230
+ static void uv__tty_queue_read(uv_loop_t* loop, uv_tty_t* handle) {
231
+ - if (handle->flags & UV_HANDLE_TTY_RAW) {
232
+ + if (uv__is_raw_tty_mode(handle->tty.rd.mode.mode)) {
233
+ uv__tty_queue_read_raw(loop, handle);
234
+ } else {
235
+ uv__tty_queue_read_line(loop, handle);
236
+ @@ -703,7 +731,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
237
+ handle->flags &= ~UV_HANDLE_READ_PENDING;
238
+
239
+ if (!(handle->flags & UV_HANDLE_READING) ||
240
+ - !(handle->flags & UV_HANDLE_TTY_RAW)) {
241
+ + !(uv__is_raw_tty_mode(handle->tty.rd.mode.mode))) {
242
+ goto out;
243
+ }
244
+
245
+ @@ -1056,7 +1084,7 @@ int uv__tty_read_stop(uv_tty_t* handle) {
246
+ if (!(handle->flags & UV_HANDLE_READ_PENDING))
247
+ return 0;
248
+
249
+ - if (handle->flags & UV_HANDLE_TTY_RAW) {
250
+ + if (uv__is_raw_tty_mode(handle->tty.rd.mode.mode)) {
251
+ /* Cancel raw read. Write some bullshit event to force the console wait to
252
+ * return. */
253
+ memset(&record, 0, sizeof record);
254
+ @@ -2299,7 +2327,17 @@ void uv__tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
255
+
256
+
257
+ int uv_tty_reset_mode(void) {
258
+ - /* Not necessary to do anything. */
259
+ + /**
260
+ + * Shells on Windows do know to reset output flags after a program exits,
261
+ + * but not necessarily input flags, so we do that for them.
262
+ + */
263
+ + if (
264
+ + uv__tty_console_handle_in != INVALID_HANDLE_VALUE &&
265
+ + uv__tty_console_in_original_mode != (DWORD)-1 &&
266
+ + InterlockedExchange(&uv__tty_console_in_need_mode_reset, 0) != 0
267
+ + ) {
268
+ + SetConsoleMode(uv__tty_console_handle_in, uv__tty_console_in_original_mode);
269
+ + }
270
+ return 0;
271
+ }
272
+
273
+ @@ -2396,7 +2434,7 @@ static void uv__tty_console_signal_resize(void) {
274
+ CONSOLE_SCREEN_BUFFER_INFO sb_info;
275
+ int width, height;
276
+
277
+ - if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info))
278
+ + if (!GetConsoleScreenBufferInfo(uv__tty_console_handle_out, &sb_info))
279
+ return;
280
+
281
+ width = sb_info.dwSize.X;
282
+ diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc
283
+ index d2bd9c383abe..bbc3fd37f992 100644
284
+ --- a/src/tty_wrap.cc
285
+ +++ b/src/tty_wrap.cc
286
+ @@ -112,7 +112,9 @@ void TTYWrap::SetRawMode(const FunctionCallbackInfo<Value>& args) {
287
+ TTYWrap* wrap;
288
+ ASSIGN_OR_RETURN_UNWRAP(
289
+ &wrap, args.This(), args.GetReturnValue().Set(UV_EBADF));
290
+ - int err = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue());
291
+ + int err = uv_tty_set_mode(
292
+ + &wrap->handle_,
293
+ + args[0]->IsTrue() ? UV_TTY_MODE_RAW_VT : UV_TTY_MODE_NORMAL);
294
+ args.GetReturnValue().Set(err);
295
+ }
296
+
0 commit comments