summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tool_doswin.c62
-rw-r--r--src/tool_main.c57
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();