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:
@@ -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)
|
||||
{
|
||||
|
@@ -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
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user