1 use std::io; 2 use std::os::windows::io::{AsRawHandle, RawHandle}; 3 use std::process::Child; 4 use winapi::shared::winerror::WAIT_TIMEOUT; 5 use winapi::um::synchapi::WaitForSingleObject; 6 use winapi::um::winbase::{INFINITE, WAIT_OBJECT_0}; 7 use winapi::um::winnt::HANDLE; 8 9 pub struct Handle(RawHandle); 10 11 // Kind of like a child PID on Unix, it's important not to keep the handle 12 // around after the child has been cleaned up. The best solution would be to 13 // have the handle actually borrow the child, but we need to keep the child 14 // unborrowed. Instead we just avoid storing them. get_handle(child: &Child) -> Handle15pub fn get_handle(child: &Child) -> Handle { 16 Handle(child.as_raw_handle()) 17 } 18 19 // This is very similar to libstd's Child::wait implementation, because the 20 // basic wait on Windows doesn't reap. The main difference is that this can be 21 // called without &mut Child. wait_without_reaping(handle: Handle) -> io::Result<()>22pub fn wait_without_reaping(handle: Handle) -> io::Result<()> { 23 let wait_ret = unsafe { WaitForSingleObject(handle.0 as HANDLE, INFINITE) }; 24 if wait_ret != WAIT_OBJECT_0 { 25 Err(io::Error::last_os_error()) 26 } else { 27 Ok(()) 28 } 29 } 30 try_wait_without_reaping(handle: Handle) -> io::Result<bool>31pub fn try_wait_without_reaping(handle: Handle) -> io::Result<bool> { 32 let wait_ret = unsafe { WaitForSingleObject(handle.0 as HANDLE, 0) }; 33 if wait_ret == WAIT_OBJECT_0 { 34 // Child has exited. 35 Ok(true) 36 } else if wait_ret == WAIT_TIMEOUT { 37 // Child has not exited yet. 38 Ok(false) 39 } else { 40 Err(io::Error::last_os_error()) 41 } 42 } 43