Skip to main content

nuclei/process/
stdio.rs

1//! A child's piped standard streams, as async pipes: the driver reads and
2//! writes them (see `io::source`), as it does any byte stream.
3
4use core::pin::Pin;
5use core::task::{Context, Poll};
6use std::io;
7
8use futures_io::{AsyncRead, AsyncWrite};
9
10use crate::io::Handle;
11
12macro_rules! child_pipe {
13    ($($(#[$doc:meta])* $name:ident),*) => {$(
14        $(#[$doc])*
15        #[derive(Debug)]
16        pub struct $name(Handle<std::process::$name>);
17
18        impl $name {
19            pub(crate) fn new(pipe: std::process::$name) -> io::Result<Self> {
20                Handle::new(pipe).map(Self)
21            }
22        }
23    )*};
24}
25
26child_pipe!(
27    /// The child's stdin: write to it, and drop it (or [`close`]) to end it.
28    ///
29    /// [`close`]: futures_io::AsyncWrite::poll_close
30    ChildStdin,
31    /// The child's stdout.
32    ChildStdout,
33    /// The child's stderr.
34    ChildStderr
35);
36
37impl AsyncWrite for ChildStdin {
38    fn poll_write(
39        self: Pin<&mut Self>,
40        cx: &mut Context<'_>,
41        buf: &[u8],
42    ) -> Poll<io::Result<usize>> {
43        self.0.source().poll_write(cx, buf)
44    }
45
46    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
47        self.0.source().poll_flush(cx)
48    }
49
50    fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
51        self.0.source().poll_close(cx)
52    }
53}
54
55impl AsyncRead for ChildStdout {
56    fn poll_read(
57        self: Pin<&mut Self>,
58        cx: &mut Context<'_>,
59        buf: &mut [u8],
60    ) -> Poll<io::Result<usize>> {
61        self.0.source().poll_read(cx, buf, false)
62    }
63}
64
65impl AsyncRead for ChildStderr {
66    fn poll_read(
67        self: Pin<&mut Self>,
68        cx: &mut Context<'_>,
69        buf: &mut [u8],
70    ) -> Poll<io::Result<usize>> {
71        self.0.source().poll_read(cx, buf, false)
72    }
73}