compio_process/
windows.rs1use std::{
2 io,
3 os::windows::{io::AsRawHandle, process::ExitStatusExt},
4 pin::Pin,
5 process,
6 task::Poll,
7};
8
9use compio_buf::{BufResult, IntoInner, IoBuf, IoBufMut};
10use compio_driver::{
11 AsRawFd, OpCode, OpType, RawFd, SharedFd, ToSharedFd,
12 op::{BufResultExt, Recv, Send},
13 syscall,
14};
15use compio_io::{AsyncRead, AsyncWrite};
16use windows_sys::Win32::System::{IO::OVERLAPPED, Threading::GetExitCodeProcess};
17
18use crate::{ChildStderr, ChildStdin, ChildStdout};
19
20struct WaitProcess {
21 child: process::Child,
22}
23
24impl WaitProcess {
25 pub fn new(child: process::Child) -> Self {
26 Self { child }
27 }
28}
29
30impl OpCode for WaitProcess {
31 fn op_type(&self) -> OpType {
32 OpType::Event(self.child.as_raw_handle() as _)
33 }
34
35 unsafe fn operate(self: Pin<&mut Self>, _optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
36 let mut code = 0;
37 syscall!(
38 BOOL,
39 GetExitCodeProcess(self.child.as_raw_handle() as _, &mut code)
40 )?;
41 Poll::Ready(Ok(code as _))
42 }
43}
44
45pub async fn child_wait(child: process::Child) -> io::Result<process::ExitStatus> {
46 let op = WaitProcess::new(child);
47 let code = compio_runtime::submit(op).await.0?;
48 Ok(process::ExitStatus::from_raw(code as _))
49}
50
51impl AsRawFd for ChildStdout {
52 fn as_raw_fd(&self) -> RawFd {
53 self.0.as_raw_fd()
54 }
55}
56
57impl ToSharedFd<process::ChildStdout> for ChildStdout {
58 fn to_shared_fd(&self) -> SharedFd<process::ChildStdout> {
59 self.0.to_shared_fd()
60 }
61}
62
63impl AsyncRead for ChildStdout {
64 async fn read<B: IoBufMut>(&mut self, buffer: B) -> BufResult<usize, B> {
65 let fd = self.to_shared_fd();
66 let op = Recv::new(fd, buffer);
67 compio_runtime::submit(op).await.into_inner().map_advanced()
68 }
69}
70
71impl AsRawFd for ChildStderr {
72 fn as_raw_fd(&self) -> RawFd {
73 self.0.as_raw_fd()
74 }
75}
76
77impl ToSharedFd<process::ChildStderr> for ChildStderr {
78 fn to_shared_fd(&self) -> SharedFd<process::ChildStderr> {
79 self.0.to_shared_fd()
80 }
81}
82
83impl AsyncRead for ChildStderr {
84 async fn read<B: IoBufMut>(&mut self, buffer: B) -> BufResult<usize, B> {
85 let fd = self.to_shared_fd();
86 let op = Recv::new(fd, buffer);
87 compio_runtime::submit(op).await.into_inner().map_advanced()
88 }
89}
90
91impl AsRawFd for ChildStdin {
92 fn as_raw_fd(&self) -> RawFd {
93 self.0.as_raw_fd()
94 }
95}
96
97impl ToSharedFd<process::ChildStdin> for ChildStdin {
98 fn to_shared_fd(&self) -> SharedFd<process::ChildStdin> {
99 self.0.to_shared_fd()
100 }
101}
102
103impl AsyncWrite for ChildStdin {
104 async fn write<T: IoBuf>(&mut self, buffer: T) -> BufResult<usize, T> {
105 let fd = self.to_shared_fd();
106 let op = Send::new(fd, buffer);
107 compio_runtime::submit(op).await.into_inner()
108 }
109
110 async fn flush(&mut self) -> io::Result<()> {
111 Ok(())
112 }
113
114 async fn shutdown(&mut self) -> io::Result<()> {
115 Ok(())
116 }
117}