1use std::{io, panic::resume_unwind, process};
2
3use compio_buf::{BufResult, IntoInner, IoBuf, IoBufMut};
4use compio_driver::{
5 AsRawFd, RawFd, SharedFd, ToSharedFd,
6 op::{BufResultExt, Recv, Send},
7};
8use compio_io::{AsyncRead, AsyncWrite};
9
10use crate::{ChildStderr, ChildStdin, ChildStdout};
11
12pub async fn child_wait(mut child: process::Child) -> io::Result<process::ExitStatus> {
13 compio_runtime::spawn_blocking(move || child.wait())
14 .await
15 .unwrap_or_else(|e| resume_unwind(e))
16}
17
18impl AsRawFd for ChildStdout {
19 fn as_raw_fd(&self) -> RawFd {
20 self.0.as_raw_fd()
21 }
22}
23
24impl ToSharedFd<process::ChildStdout> for ChildStdout {
25 fn to_shared_fd(&self) -> SharedFd<process::ChildStdout> {
26 self.0.to_shared_fd()
27 }
28}
29
30impl AsyncRead for ChildStdout {
31 async fn read<B: IoBufMut>(&mut self, buffer: B) -> BufResult<usize, B> {
32 let fd = self.to_shared_fd();
33 let op = Recv::new(fd, buffer);
34 compio_runtime::submit(op).await.into_inner().map_advanced()
35 }
36}
37
38impl AsRawFd for ChildStderr {
39 fn as_raw_fd(&self) -> RawFd {
40 self.0.as_raw_fd()
41 }
42}
43
44impl ToSharedFd<process::ChildStderr> for ChildStderr {
45 fn to_shared_fd(&self) -> SharedFd<process::ChildStderr> {
46 self.0.to_shared_fd()
47 }
48}
49
50impl AsyncRead for ChildStderr {
51 async fn read<B: IoBufMut>(&mut self, buffer: B) -> BufResult<usize, B> {
52 let fd = self.to_shared_fd();
53 let op = Recv::new(fd, buffer);
54 compio_runtime::submit(op).await.into_inner().map_advanced()
55 }
56}
57
58impl AsRawFd for ChildStdin {
59 fn as_raw_fd(&self) -> RawFd {
60 self.0.as_raw_fd()
61 }
62}
63
64impl ToSharedFd<process::ChildStdin> for ChildStdin {
65 fn to_shared_fd(&self) -> SharedFd<process::ChildStdin> {
66 self.0.to_shared_fd()
67 }
68}
69
70impl AsyncWrite for ChildStdin {
71 async fn write<T: IoBuf>(&mut self, buffer: T) -> BufResult<usize, T> {
72 let fd = self.to_shared_fd();
73 let op = Send::new(fd, buffer);
74 compio_runtime::submit(op).await.into_inner()
75 }
76
77 async fn flush(&mut self) -> io::Result<()> {
78 Ok(())
79 }
80
81 async fn shutdown(&mut self) -> io::Result<()> {
82 Ok(())
83 }
84}