diff options
author | Ron Yorston <rmy@pobox.com> | 2020-01-06 15:18:58 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-01-06 15:18:58 +0000 |
commit | fe5a564b429e8472c68f931cc9b53815b889bb1f (patch) | |
tree | 79817b75e773adf08dfd6527b45c53e429905df7 | |
parent | c0f40af509c4a4face7240e5dbabacaff02e669a (diff) | |
download | busybox-w32-fe5a564b429e8472c68f931cc9b53815b889bb1f.tar.gz busybox-w32-fe5a564b429e8472c68f931cc9b53815b889bb1f.tar.bz2 busybox-w32-fe5a564b429e8472c68f931cc9b53815b889bb1f.zip |
winansi: fix escape processing in Windows 10 release 1809
As reported in GitHub issue #177, ANSI escape sequences don't work
reliably after shell redirection.
The problem appears to be due to a change in the behaviour of dup2()
in Windows 10 release 1809. The escape handling code kept a copy of
the console handle for internal use. Prior to Windows 10 release 1809
this worked; since then unwinding shell redirections results in the actual
console handle changing from time to time for reasons that are unknowable
without access to the source code.
Fix this by always fetching the console handle instead of caching it.
-rw-r--r-- | win32/winansi.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/win32/winansi.c b/win32/winansi.c index f5d836bd2..f45970747 100644 --- a/win32/winansi.c +++ b/win32/winansi.c | |||
@@ -21,22 +21,20 @@ | |||
21 | #undef read | 21 | #undef read |
22 | #undef getc | 22 | #undef getc |
23 | 23 | ||
24 | static HANDLE console = INVALID_HANDLE_VALUE; | ||
25 | static HANDLE console_in = INVALID_HANDLE_VALUE; | ||
26 | static WORD plain_attr; | 24 | static WORD plain_attr; |
27 | static WORD attr; | 25 | static WORD attr; |
28 | static int negative; | 26 | static int negative; |
29 | 27 | ||
28 | static HANDLE get_console(void) | ||
29 | { | ||
30 | return GetStdHandle(STD_OUTPUT_HANDLE); | ||
31 | } | ||
32 | |||
30 | static void init(void) | 33 | static void init(void) |
31 | { | 34 | { |
35 | HANDLE console = get_console(); | ||
32 | CONSOLE_SCREEN_BUFFER_INFO sbi; | 36 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
33 | 37 | ||
34 | if (console != INVALID_HANDLE_VALUE || console_in != INVALID_HANDLE_VALUE) | ||
35 | return; | ||
36 | |||
37 | console = GetStdHandle(STD_OUTPUT_HANDLE); | ||
38 | console_in = GetStdHandle(STD_INPUT_HANDLE); | ||
39 | |||
40 | if (GetConsoleScreenBufferInfo(console, &sbi)) { | 38 | if (GetConsoleScreenBufferInfo(console, &sbi)) { |
41 | attr = plain_attr = sbi.wAttributes; | 39 | attr = plain_attr = sbi.wAttributes; |
42 | negative = 0; | 40 | negative = 0; |
@@ -46,13 +44,13 @@ static void init(void) | |||
46 | static int is_console(int fd) | 44 | static int is_console(int fd) |
47 | { | 45 | { |
48 | init(); | 46 | init(); |
49 | return isatty(fd) && console != INVALID_HANDLE_VALUE; | 47 | return isatty(fd) && get_console() != INVALID_HANDLE_VALUE; |
50 | } | 48 | } |
51 | 49 | ||
52 | static int is_console_in(int fd) | 50 | static int is_console_in(int fd) |
53 | { | 51 | { |
54 | init(); | 52 | init(); |
55 | return isatty(fd) && console_in != INVALID_HANDLE_VALUE; | 53 | return isatty(fd) && GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE; |
56 | } | 54 | } |
57 | 55 | ||
58 | static int skip_ansi_emulation(void) | 56 | static int skip_ansi_emulation(void) |
@@ -87,20 +85,13 @@ static HANDLE dup_handle(HANDLE h) | |||
87 | static void use_alt_buffer(int flag) | 85 | static void use_alt_buffer(int flag) |
88 | { | 86 | { |
89 | static HANDLE console_orig = INVALID_HANDLE_VALUE; | 87 | static HANDLE console_orig = INVALID_HANDLE_VALUE; |
90 | static int initialised = FALSE; | ||
91 | CONSOLE_SCREEN_BUFFER_INFO sbi; | 88 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
92 | HANDLE h; | 89 | HANDLE console, h; |
93 | 90 | ||
94 | init(); | 91 | init(); |
95 | 92 | ||
96 | if (console == INVALID_HANDLE_VALUE) | 93 | console = get_console(); |
97 | return; | 94 | console_orig = dup_handle(console); |
98 | |||
99 | if (!initialised) { | ||
100 | console_orig = dup_handle(console); | ||
101 | initialised = TRUE; | ||
102 | } | ||
103 | |||
104 | if (console_orig == INVALID_HANDLE_VALUE) | 95 | if (console_orig == INVALID_HANDLE_VALUE) |
105 | return; | 96 | return; |
106 | 97 | ||
@@ -120,6 +111,7 @@ static void use_alt_buffer(int flag) | |||
120 | if (h == INVALID_HANDLE_VALUE) | 111 | if (h == INVALID_HANDLE_VALUE) |
121 | return; | 112 | return; |
122 | 113 | ||
114 | console = get_console(); | ||
123 | if (GetConsoleScreenBufferInfo(console, &sbi)) | 115 | if (GetConsoleScreenBufferInfo(console, &sbi)) |
124 | SetConsoleScreenBufferSize(h, sbi.dwSize); | 116 | SetConsoleScreenBufferSize(h, sbi.dwSize); |
125 | } | 117 | } |
@@ -141,6 +133,7 @@ static void use_alt_buffer(int flag) | |||
141 | 133 | ||
142 | static void set_console_attr(void) | 134 | static void set_console_attr(void) |
143 | { | 135 | { |
136 | HANDLE console = get_console(); | ||
144 | WORD attributes = attr; | 137 | WORD attributes = attr; |
145 | if (negative) { | 138 | if (negative) { |
146 | attributes &= ~FOREGROUND_ALL; | 139 | attributes &= ~FOREGROUND_ALL; |
@@ -167,6 +160,7 @@ static void set_console_attr(void) | |||
167 | 160 | ||
168 | static void clear_buffer(DWORD len, COORD pos) | 161 | static void clear_buffer(DWORD len, COORD pos) |
169 | { | 162 | { |
163 | HANDLE console = get_console(); | ||
170 | DWORD dummy; | 164 | DWORD dummy; |
171 | 165 | ||
172 | FillConsoleOutputCharacterA(console, ' ', len, pos, &dummy); | 166 | FillConsoleOutputCharacterA(console, ' ', len, pos, &dummy); |
@@ -175,6 +169,7 @@ static void clear_buffer(DWORD len, COORD pos) | |||
175 | 169 | ||
176 | static void erase_in_line(void) | 170 | static void erase_in_line(void) |
177 | { | 171 | { |
172 | HANDLE console = get_console(); | ||
178 | CONSOLE_SCREEN_BUFFER_INFO sbi; | 173 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
179 | 174 | ||
180 | if (!GetConsoleScreenBufferInfo(console, &sbi)) | 175 | if (!GetConsoleScreenBufferInfo(console, &sbi)) |
@@ -184,6 +179,7 @@ static void erase_in_line(void) | |||
184 | 179 | ||
185 | static void erase_till_end_of_screen(void) | 180 | static void erase_till_end_of_screen(void) |
186 | { | 181 | { |
182 | HANDLE console = get_console(); | ||
187 | CONSOLE_SCREEN_BUFFER_INFO sbi; | 183 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
188 | DWORD len; | 184 | DWORD len; |
189 | 185 | ||
@@ -196,6 +192,7 @@ static void erase_till_end_of_screen(void) | |||
196 | 192 | ||
197 | void reset_screen(void) | 193 | void reset_screen(void) |
198 | { | 194 | { |
195 | HANDLE console = get_console(); | ||
199 | CONSOLE_SCREEN_BUFFER_INFO sbi; | 196 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
200 | COORD pos = { 0, 0 }; | 197 | COORD pos = { 0, 0 }; |
201 | 198 | ||
@@ -208,6 +205,7 @@ void reset_screen(void) | |||
208 | 205 | ||
209 | void move_cursor_row(int n) | 206 | void move_cursor_row(int n) |
210 | { | 207 | { |
208 | HANDLE console = get_console(); | ||
211 | CONSOLE_SCREEN_BUFFER_INFO sbi; | 209 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
212 | 210 | ||
213 | if(!GetConsoleScreenBufferInfo(console, &sbi)) | 211 | if(!GetConsoleScreenBufferInfo(console, &sbi)) |
@@ -218,6 +216,7 @@ void move_cursor_row(int n) | |||
218 | 216 | ||
219 | static void move_cursor_column(int n) | 217 | static void move_cursor_column(int n) |
220 | { | 218 | { |
219 | HANDLE console = get_console(); | ||
221 | CONSOLE_SCREEN_BUFFER_INFO sbi; | 220 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
222 | 221 | ||
223 | if (!GetConsoleScreenBufferInfo(console, &sbi)) | 222 | if (!GetConsoleScreenBufferInfo(console, &sbi)) |
@@ -228,6 +227,7 @@ static void move_cursor_column(int n) | |||
228 | 227 | ||
229 | static void move_cursor(int x, int y) | 228 | static void move_cursor(int x, int y) |
230 | { | 229 | { |
230 | HANDLE console = get_console(); | ||
231 | COORD pos; | 231 | COORD pos; |
232 | CONSOLE_SCREEN_BUFFER_INFO sbi; | 232 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
233 | 233 | ||