mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-24 09:09:43 -05: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))
|
, FD_(cm_fileno(file))
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD mode;
|
|
||||||
auto h = reinterpret_cast<HANDLE>(_get_osfhandle(this->FD_));
|
auto h = reinterpret_cast<HANDLE>(_get_osfhandle(this->FD_));
|
||||||
if (GetConsoleMode(h, &mode)) {
|
if (GetConsoleMode(h, &this->ConsoleOrigMode_)) {
|
||||||
this->Console_ = h;
|
this->Console_ = h;
|
||||||
DWORD vtMode = mode |
|
DWORD vtMode = this->ConsoleOrigMode_ |
|
||||||
(direction == Direction::In ? ENABLE_VIRTUAL_TERMINAL_INPUT
|
(direction == Direction::In ? ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||||
: ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
: ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||||
if (SetConsoleMode(this->Console_, vtMode)) {
|
if (SetConsoleMode(this->Console_, vtMode)) {
|
||||||
this->Kind_ = TermKind::VT100;
|
this->Kind_ = TermKind::VT100;
|
||||||
} else {
|
} else {
|
||||||
SetConsoleMode(this->Console_, mode);
|
SetConsoleMode(this->Console_, this->ConsoleOrigMode_);
|
||||||
this->Kind_ = TermKind::Console;
|
this->Kind_ = TermKind::Console;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,6 +136,18 @@ Stream::Stream(std::ios& s, FILE* file, Direction direction)
|
|||||||
#endif
|
#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)
|
IStream::IStream(std::istream& is, FILE* file)
|
||||||
: Stream(is, file, Direction::In)
|
: Stream(is, file, Direction::In)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Stream(std::ios& s, FILE* file, Direction direction);
|
Stream(std::ios& s, FILE* file, Direction direction);
|
||||||
|
~Stream(); // NOLINT(performance-trivially-destructible)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ios& IOS_;
|
std::ios& IOS_;
|
||||||
@@ -61,6 +62,7 @@ private:
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void* Console_ = nullptr;
|
void* Console_ = nullptr;
|
||||||
|
unsigned long ConsoleOrigMode_ = 0;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user