Skip to content

Commit 6bcb6f2

Browse files
authored
chore(deps): update patch for bracketed paste on Windows MONGOSH-1999 (#2386)
Update the patch to the commit merged into libuv and add a small Node.js source modification that will need to go into an upcoming Node.js release in order for the patch to take effect. Refs: libuv/libuv@843b64f
1 parent d4d7980 commit 6bcb6f2

File tree

1 file changed

+265
-15
lines changed

1 file changed

+265
-15
lines changed
Lines changed: 265 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,94 @@
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);
190
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
392
--- a/deps/uv/src/win/tty.c
493
+++ b/deps/uv/src/win/tty.c
594
@@ -58,6 +58,9 @@
@@ -9,38 +98,199 @@ index 7e1f15544b17..37bc2c4ace57 100644
998
+#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
1099
+#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
11100
+#endif
12-
101+
13102
#define CURSOR_SIZE_SMALL 25
14103
#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+
17179
int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
18180
DWORD flags;
19181
+ DWORD try_set_flags;
20182
unsigned char was_reading;
21183
uv_alloc_cb alloc_cb;
22184
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;
24195
switch (mode) {
25196
case UV_TTY_MODE_NORMAL:
26197
flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
27-
+ try_set_flags = 0;
28198
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 */
29203
case UV_TTY_MODE_RAW:
30204
flags = ENABLE_WINDOW_INPUT;
31-
+ try_set_flags = ENABLE_VIRTUAL_TERMINAL_INPUT;
32205
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) {
36207
}
37-
208+
38209
uv_sem_wait(&uv_tty_output_lock);
39210
- 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)) {
44213
err = uv_translate_sys_error(GetLastError());
45214
uv_sem_post(&uv_tty_output_lock);
46215
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

Comments
 (0)