summaryrefslogtreecommitdiffstats
path: root/wincolor
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-06-19 08:39:34 -0700
committerAndrew Gallant <jamslam@gmail.com>2017-06-19 12:57:45 -0400
commit7763c98188de44bca1136712ce40b60e031496bd (patch)
treecebab72b15172fc7fcc5d6b1a4a33bea3827cdaf /wincolor
parent06393f888c664d0fe2a31422a05b60f6d1bd0b6a (diff)
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`.
Diffstat (limited to 'wincolor')
-rw-r--r--wincolor/src/win.rs21
1 files changed, 7 insertions, 14 deletions
diff --git a/wincolor/src/win.rs b/wincolor/src/win.rs
index e61240b7..c0ad8359 100644
--- a/wincolor/src/win.rs
+++ b/wincolor/src/win.rs
@@ -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());