diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tool_doswin.c | 62 | ||||
-rw-r--r-- | src/tool_main.c | 57 |
2 files changed, 66 insertions, 53 deletions
diff --git a/src/tool_doswin.c b/src/tool_doswin.c index 2ae6ba788..b70100abe 100644 --- a/src/tool_doswin.c +++ b/src/tool_doswin.c @@ -28,6 +28,7 @@ #endif #ifdef WIN32 +# include <stdlib.h> # include <tlhelp32.h> # include "tool_cfgable.h" # include "tool_libinfo.h" @@ -702,6 +703,64 @@ cleanup: return slist; } +/* The terminal settings to restore on exit */ +static struct TerminalSettings { + HANDLE hStdOut; + DWORD dwOutputMode; + LONG valid; +} TerminalSettings; + +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#endif + +static void restore_terminal(void) +{ + if(InterlockedExchange(&TerminalSettings.valid, (LONG)FALSE)) + SetConsoleMode(TerminalSettings.hStdOut, TerminalSettings.dwOutputMode); +} + +/* This is the console signal handler. + * The system calls it in a separate thread. + */ +static BOOL WINAPI signal_handler(DWORD type) +{ + if(type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT) + restore_terminal(); + return FALSE; +} + +static void init_terminal(void) +{ + TerminalSettings.hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + /* + * Enable VT (Virtual Terminal) output. + * Note: VT mode flag can be set on any version of Windows, but VT + * processing only performed on Win10 >= Creators Update) + */ + if((TerminalSettings.hStdOut != INVALID_HANDLE_VALUE) && + GetConsoleMode(TerminalSettings.hStdOut, + &TerminalSettings.dwOutputMode) && + !(TerminalSettings.dwOutputMode & + ENABLE_VIRTUAL_TERMINAL_PROCESSING)) { + /* The signal handler is set before attempting to change the console mode + because otherwise a signal would not be caught after the change but + before the handler was installed. */ + (void)InterlockedExchange(&TerminalSettings.valid, (LONG)TRUE); + if(SetConsoleCtrlHandler(signal_handler, TRUE)) { + if(SetConsoleMode(TerminalSettings.hStdOut, + (TerminalSettings.dwOutputMode | + ENABLE_VIRTUAL_TERMINAL_PROCESSING))) { + atexit(restore_terminal); + } + else { + SetConsoleCtrlHandler(signal_handler, FALSE); + (void)InterlockedExchange(&TerminalSettings.valid, (LONG)FALSE); + } + } + } +} + LARGE_INTEGER tool_freq; bool tool_isVistaOrGreater; @@ -714,6 +773,9 @@ CURLcode win32_init(void) tool_isVistaOrGreater = false; QueryPerformanceFrequency(&tool_freq); + + init_terminal(); + return CURLE_OK; } diff --git a/src/tool_main.c b/src/tool_main.c index 16f513a43..1c4b07e7c 100644 --- a/src/tool_main.c +++ b/src/tool_main.c @@ -23,6 +23,10 @@ #include <sys/stat.h> +#ifdef WIN32 +#include <tchar.h> +#endif + #ifdef HAVE_SIGNAL_H #include <signal.h> #endif @@ -225,51 +229,6 @@ static void main_free(struct GlobalConfig *config) config->last = NULL; } -#ifdef WIN32 -/* TerminalSettings for Windows */ -static struct TerminalSettings { - HANDLE hStdOut; - DWORD dwOutputMode; -} TerminalSettings; - -static void configure_terminal(void) -{ - /* - * If we're running Windows, enable VT output. - * Note: VT mode flag can be set on any version of Windows, but VT - * processing only performed on Win10 >= Creators Update) - */ - - /* Define the VT flags in case we're building with an older SDK */ -#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING - #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 -#endif - - memset(&TerminalSettings, 0, sizeof(TerminalSettings)); - - /* Enable VT output */ - TerminalSettings.hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); - if((TerminalSettings.hStdOut != INVALID_HANDLE_VALUE) - && (GetConsoleMode(TerminalSettings.hStdOut, - &TerminalSettings.dwOutputMode))) { - SetConsoleMode(TerminalSettings.hStdOut, - TerminalSettings.dwOutputMode - | ENABLE_VIRTUAL_TERMINAL_PROCESSING); - } -} -#else -#define configure_terminal() -#endif - -static void restore_terminal(void) -{ -#ifdef WIN32 - /* Restore Console output mode and codepage to whatever they were - * when Curl started */ - SetConsoleMode(TerminalSettings.hStdOut, TerminalSettings.dwOutputMode); -#endif -} - /* ** curl tool main function. */ @@ -284,7 +243,6 @@ int main(int argc, char *argv[]) memset(&global, 0, sizeof(global)); #ifdef WIN32 -#ifdef _tcscmp /* Undocumented diagnostic option to list the full paths of all loaded modules. This is purposely pre-init. */ if(argc == 2 && !_tcscmp(argv[1], _T("--dump-module-paths"))) { @@ -294,7 +252,6 @@ int main(int argc, char *argv[]) curl_slist_free_all(head); return head ? 0 : 1; } -#endif /* _tcscmp */ /* win32_init must be called before other init routines. */ result = win32_init(); if(result) { @@ -303,9 +260,6 @@ int main(int argc, char *argv[]) } #endif - /* Perform any platform-specific terminal configuration */ - configure_terminal(); - main_checkfds(); #if defined(HAVE_SIGNAL) && defined(SIGPIPE) @@ -326,9 +280,6 @@ int main(int argc, char *argv[]) main_free(&global); } - /* Return the terminal to its original state */ - restore_terminal(); - #ifdef __NOVELL_LIBC__ if(getenv("_IN_NETWARE_BASH_") == NULL) tool_pressanykey(); |