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_; }