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
This commit is contained in:
Brad King
2025-11-26 14:57:39 -05:00
parent 0848aac41c
commit e419429616
3 changed files with 28 additions and 0 deletions

View File

@@ -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;

View File

@@ -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

View File

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