From e419429616d8bcc3687ede7cf13fcfe074cc1ad2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 26 Nov 2025 14:57:39 -0500 Subject: [PATCH] StdIo: Restore Windows Console I/O modes on Ctrl-C Extend commit fb3e7825f3 (StdIo: Restore Windows Console I/O modes on exit, 2025-05-23, v4.1.0-rc1~114^2) to cover termination by Ctrl-C. Fixes: #27427 --- Source/cmStdIoInit.cxx | 17 +++++++++++++++++ Source/cmStdIoStream.cxx | 6 ++++++ Source/cmStdIoStream.h | 5 +++++ 3 files changed, 28 insertions(+) diff --git a/Source/cmStdIoInit.cxx b/Source/cmStdIoInit.cxx index 8c834f2dc9..a2fc50db7f 100644 --- a/Source/cmStdIoInit.cxx +++ b/Source/cmStdIoInit.cxx @@ -91,9 +91,26 @@ public: OStream StdOut{ std::cout, stdout }; OStream StdErr{ std::cerr, stderr }; + Globals(); + static Globals& Get(); }; +#ifdef _WIN32 +Globals::Globals() +{ + static auto const ctrlHandler = [](DWORD /*dwCtrlType*/) -> BOOL { + Get().StdErr.Destroy(); + Get().StdOut.Destroy(); + Get().StdIn.Destroy(); + return FALSE; + }; + SetConsoleCtrlHandler(ctrlHandler, TRUE); +} +#else +Globals::Globals() = default; +#endif + Globals& Globals::Get() { static Globals globals; diff --git a/Source/cmStdIoStream.cxx b/Source/cmStdIoStream.cxx index b1cb19c0df..baea8dfcbe 100644 --- a/Source/cmStdIoStream.cxx +++ b/Source/cmStdIoStream.cxx @@ -145,10 +145,16 @@ Stream::Stream(std::ios& s, FILE* file, Direction direction) #ifdef _WIN32 Stream::~Stream() +{ + this->Destroy(); +} + +void Stream::Destroy() { if (this->Console_) { this->IOS_.rdbuf()->pubsync(); SetConsoleMode(this->Console_, this->ConsoleOrigMode_); + this->Console_ = nullptr; } } #else diff --git a/Source/cmStdIoStream.h b/Source/cmStdIoStream.h index 8ff84f93cf..f94fa22d9f 100644 --- a/Source/cmStdIoStream.h +++ b/Source/cmStdIoStream.h @@ -30,6 +30,11 @@ enum class TermKind */ class Stream { +#ifdef _WIN32 + friend class Globals; + void Destroy(); +#endif + public: /** The kind of terminal to which the stream is attached, if any. */ TermKind Kind() const { return this->Kind_; }