diff --git a/src/pty/conpty.rs b/src/pty/conpty.rs index f37ca68de..083188970 100644 --- a/src/pty/conpty.rs +++ b/src/pty/conpty.rs @@ -1,3 +1,4 @@ +use crate::pty::ownedhandle::OwnedHandle; use failure::Error; use lazy_static::lazy_static; use shared_library::shared_library; @@ -13,7 +14,7 @@ use std::ptr; use std::sync::{Arc, Mutex}; use winapi::shared::minwindef::DWORD; use winapi::shared::winerror::{HRESULT, S_OK}; -use winapi::um::fileapi::{ReadFile, WriteFile}; +use winapi::um::fileapi::WriteFile; use winapi::um::handleapi::*; use winapi::um::minwinbase::STILL_ACTIVE; use winapi::um::namedpipeapi::CreatePipe; @@ -396,73 +397,6 @@ impl PsuedoCon { } } -#[derive(Debug)] -pub struct OwnedHandle { - handle: HANDLE, -} -unsafe impl Send for OwnedHandle {} -impl Drop for OwnedHandle { - fn drop(&mut self) { - if self.handle != INVALID_HANDLE_VALUE && !self.handle.is_null() { - unsafe { CloseHandle(self.handle) }; - } - } -} - -impl OwnedHandle { - pub fn new(handle: HANDLE) -> Self { - Self { handle } - } - pub fn try_clone(&self) -> Result { - if self.handle == INVALID_HANDLE_VALUE || self.handle.is_null() { - return Ok(OwnedHandle { - handle: self.handle, - }); - } - - let proc = unsafe { GetCurrentProcess() }; - let mut duped = INVALID_HANDLE_VALUE; - let ok = unsafe { - DuplicateHandle( - proc, - self.handle as *mut _, - proc, - &mut duped, - 0, - 0, - winapi::um::winnt::DUPLICATE_SAME_ACCESS, - ) - }; - if ok == 0 { - Err(IoError::last_os_error()) - } else { - Ok(OwnedHandle { - handle: duped as *mut _, - }) - } - } -} - -impl io::Read for OwnedHandle { - fn read(&mut self, buf: &mut [u8]) -> Result { - let mut num_read = 0; - let ok = unsafe { - ReadFile( - self.handle as *mut _, - buf.as_mut_ptr() as *mut _, - buf.len() as u32, - &mut num_read, - ptr::null_mut(), - ) - }; - if ok == 0 { - Err(IoError::last_os_error()) - } else { - Ok(num_read as usize) - } - } -} - struct Inner { con: PsuedoCon, readable: OwnedHandle, @@ -534,21 +468,7 @@ impl MasterPty { impl io::Write for MasterPty { fn write(&mut self, buf: &[u8]) -> Result { - let mut num_wrote = 0; - let ok = unsafe { - WriteFile( - self.inner.lock().unwrap().writable.handle as *mut _, - buf.as_ptr() as *const _, - buf.len() as u32, - &mut num_wrote, - ptr::null_mut(), - ) - }; - if ok == 0 { - Err(IoError::last_os_error()) - } else { - Ok(num_wrote as usize) - } + self.inner.lock().unwrap().writable.write(buf) } fn flush(&mut self) -> Result<(), io::Error> { Ok(()) diff --git a/src/pty/mod.rs b/src/pty/mod.rs index 68f67f1cc..bcade279b 100644 --- a/src/pty/mod.rs +++ b/src/pty/mod.rs @@ -1,5 +1,7 @@ #[cfg(windows)] pub mod conpty; +#[cfg(windows)] +pub mod ownedhandle; #[cfg(unix)] pub mod unix; #[cfg(windows)] diff --git a/src/pty/ownedhandle.rs b/src/pty/ownedhandle.rs new file mode 100644 index 000000000..daf9e8b37 --- /dev/null +++ b/src/pty/ownedhandle.rs @@ -0,0 +1,96 @@ +use std::io::{self, Error as IoError}; +use std::os::windows::raw::HANDLE; +use std::ptr; +use winapi::um::fileapi::*; +use winapi::um::handleapi::*; +use winapi::um::processthreadsapi::*; + +#[derive(Debug)] +pub struct OwnedHandle { + pub handle: HANDLE, +} +unsafe impl Send for OwnedHandle {} +impl Drop for OwnedHandle { + fn drop(&mut self) { + if self.handle != INVALID_HANDLE_VALUE && !self.handle.is_null() { + unsafe { CloseHandle(self.handle) }; + } + } +} + +impl OwnedHandle { + pub fn new(handle: HANDLE) -> Self { + Self { handle } + } + pub fn try_clone(&self) -> Result { + if self.handle == INVALID_HANDLE_VALUE || self.handle.is_null() { + return Ok(OwnedHandle { + handle: self.handle, + }); + } + + let proc = unsafe { GetCurrentProcess() }; + let mut duped = INVALID_HANDLE_VALUE; + let ok = unsafe { + DuplicateHandle( + proc, + self.handle as *mut _, + proc, + &mut duped, + 0, + 0, + winapi::um::winnt::DUPLICATE_SAME_ACCESS, + ) + }; + if ok == 0 { + Err(IoError::last_os_error()) + } else { + Ok(OwnedHandle { + handle: duped as *mut _, + }) + } + } +} + +impl io::Read for OwnedHandle { + fn read(&mut self, buf: &mut [u8]) -> Result { + let mut num_read = 0; + let ok = unsafe { + ReadFile( + self.handle as *mut _, + buf.as_mut_ptr() as *mut _, + buf.len() as u32, + &mut num_read, + ptr::null_mut(), + ) + }; + if ok == 0 { + Err(IoError::last_os_error()) + } else { + Ok(num_read as usize) + } + } +} + +impl io::Write for OwnedHandle { + fn write(&mut self, buf: &[u8]) -> Result { + let mut num_wrote = 0; + let ok = unsafe { + WriteFile( + self.handle as *mut _, + buf.as_ptr() as *const _, + buf.len() as u32, + &mut num_wrote, + ptr::null_mut(), + ) + }; + if ok == 0 { + Err(IoError::last_os_error()) + } else { + Ok(num_wrote as usize) + } + } + fn flush(&mut self) -> Result<(), io::Error> { + Ok(()) + } +} diff --git a/src/pty/winpty/safe.rs b/src/pty/winpty/safe.rs index 5d37b615e..e08d7db9f 100644 --- a/src/pty/winpty/safe.rs +++ b/src/pty/winpty/safe.rs @@ -2,7 +2,7 @@ //! the API exported by winpty.dll. //! https://github.com/rprichard/winpty/blob/master/src/include/winpty.h use super::sys::*; -use crate::pty::conpty::OwnedHandle; +use crate::pty::ownedhandle::OwnedHandle; use bitflags::bitflags; use failure::{format_err, Error}; use std::ffi::{OsStr, OsString};