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