diff options
author | Alex Crichton <alex@alexcrichton.com> | 2017-06-19 08:39:34 -0700 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2017-06-19 12:57:45 -0400 |
commit | 7763c98188de44bca1136712ce40b60e031496bd (patch) | |
tree | cebab72b15172fc7fcc5d6b1a4a33bea3827cdaf /wincolor | |
parent | 06393f888c664d0fe2a31422a05b60f6d1bd0b6a (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.rs | 21 |
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()); |