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