Skip to main content

compio_process/
unix.rs

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}