mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-13 21:26:27 +02:00
wincolor: Re-fetch the console on all calls
The primary motivation for this commit was rust-lang/cargo#4189 where dropping a `wincolor::Console` would call `CloseHandle` to close the console handle. Cargo creates a few `Console` instances so it ended up closing stdout a little earlier as intended! The `GetStdHandle` function returns handles I believe aren't intended to be closed (as there's no refcounting). I believe libstd doesn't close these handles. This commit also moves to calling `GetStdHandle` on demand which libstd changed to doing so recently as well, preventing caching of stale handles that change over time with calls to `SetStdHandle`.
This commit is contained in:
parent
06393f888c
commit
7763c98188
@ -2,7 +2,7 @@ use std::io;
|
||||
use std::mem;
|
||||
|
||||
use kernel32;
|
||||
use winapi::{DWORD, HANDLE, WORD};
|
||||
use winapi::{DWORD, WORD};
|
||||
use winapi::winbase::{STD_ERROR_HANDLE, STD_OUTPUT_HANDLE};
|
||||
use winapi::wincon::{
|
||||
FOREGROUND_BLUE as FG_BLUE,
|
||||
@ -30,33 +30,25 @@ const FG_WHITE: DWORD = FG_BLUE | FG_GREEN | FG_RED;
|
||||
/// stdout before setting new text attributes.
|
||||
#[derive(Debug)]
|
||||
pub struct Console {
|
||||
handle: HANDLE,
|
||||
handle_id: DWORD,
|
||||
start_attr: TextAttributes,
|
||||
cur_attr: TextAttributes,
|
||||
}
|
||||
|
||||
unsafe impl Send for Console {}
|
||||
|
||||
impl Drop for Console {
|
||||
fn drop(&mut self) {
|
||||
unsafe { kernel32::CloseHandle(self.handle); }
|
||||
}
|
||||
}
|
||||
|
||||
impl Console {
|
||||
/// Get a console for a standard I/O stream.
|
||||
fn create_for_stream(handle_id: DWORD) -> io::Result<Console> {
|
||||
let mut info = unsafe { mem::zeroed() };
|
||||
let (handle, res) = unsafe {
|
||||
let res = unsafe {
|
||||
let handle = kernel32::GetStdHandle(handle_id);
|
||||
(handle, kernel32::GetConsoleScreenBufferInfo(handle, &mut info))
|
||||
kernel32::GetConsoleScreenBufferInfo(handle, &mut info)
|
||||
};
|
||||
if res == 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
let attr = TextAttributes::from_word(info.wAttributes);
|
||||
Ok(Console {
|
||||
handle: handle,
|
||||
handle_id: handle_id,
|
||||
start_attr: attr,
|
||||
cur_attr: attr,
|
||||
})
|
||||
@ -80,7 +72,8 @@ impl Console {
|
||||
fn set(&mut self) -> io::Result<()> {
|
||||
let attr = self.cur_attr.to_word();
|
||||
let res = unsafe {
|
||||
kernel32::SetConsoleTextAttribute(self.handle, attr)
|
||||
let handle = kernel32::GetStdHandle(self.handle_id);
|
||||
kernel32::SetConsoleTextAttribute(handle, attr)
|
||||
};
|
||||
if res == 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
|
Loading…
x
Reference in New Issue
Block a user