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) -> Handle15 pub 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<()>22 pub 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>31 pub 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