1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

StdIo: Restore Windows Console I/O modes on exit

The Windows documentation [1] states:

> command-line applications should capture the initial console
> mode at startup and attempt to restore it when exiting

We set `ENABLE_VIRTUAL_TERMINAL_{INPUT,PROCESSING}` modes since
commit d6a1ff59f1 (StdIo: Provide metadata about stdin, stdout,
stderr streams, 2025-05-06).  Avoid leaking them.

[1] https://learn.microsoft.com/en-us/windows/console/console-modes

Issue: #26924
This commit is contained in:
Brad King
2025-05-23 09:03:03 -04:00
parent 12d8baadab
commit fb3e7825f3
2 changed files with 17 additions and 4 deletions

View File

@@ -115,17 +115,16 @@ Stream::Stream(std::ios& s, FILE* file, Direction direction)
, FD_(cm_fileno(file))
{
#ifdef _WIN32
DWORD mode;
auto h = reinterpret_cast<HANDLE>(_get_osfhandle(this->FD_));
if (GetConsoleMode(h, &mode)) {
if (GetConsoleMode(h, &this->ConsoleOrigMode_)) {
this->Console_ = h;
DWORD vtMode = mode |
DWORD vtMode = this->ConsoleOrigMode_ |
(direction == Direction::In ? ENABLE_VIRTUAL_TERMINAL_INPUT
: ENABLE_VIRTUAL_TERMINAL_PROCESSING);
if (SetConsoleMode(this->Console_, vtMode)) {
this->Kind_ = TermKind::VT100;
} else {
SetConsoleMode(this->Console_, mode);
SetConsoleMode(this->Console_, this->ConsoleOrigMode_);
this->Kind_ = TermKind::Console;
}
}
@@ -137,6 +136,18 @@ Stream::Stream(std::ios& s, FILE* file, Direction direction)
#endif
}
#ifdef _WIN32
Stream::~Stream()
{
if (this->Console_) {
this->IOS_.rdbuf()->pubsync();
SetConsoleMode(this->Console_, this->ConsoleOrigMode_);
}
}
#else
Stream::~Stream() = default;
#endif
IStream::IStream(std::istream& is, FILE* file)
: Stream(is, file, Direction::In)
{

View File

@@ -53,6 +53,7 @@ protected:
};
Stream(std::ios& s, FILE* file, Direction direction);
~Stream(); // NOLINT(performance-trivially-destructible)
private:
std::ios& IOS_;
@@ -61,6 +62,7 @@ private:
#ifdef _WIN32
void* Console_ = nullptr;
unsigned long ConsoleOrigMode_ = 0;
#endif
};