compio_fs/stdio/
unix.rs

1use std::io;
2
3use compio_buf::{BufResult, IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut};
4use compio_driver::{AsFd, AsRawFd, BorrowedFd, RawFd};
5use compio_io::{AsyncRead, AsyncReadManaged, AsyncWrite};
6use compio_runtime::{BorrowedBuffer, BufferPool};
7
8#[cfg(doc)]
9use super::{stderr, stdin, stdout};
10use crate::AsyncFd;
11
12#[derive(Debug)]
13struct StaticFd(RawFd);
14
15impl AsFd for StaticFd {
16    fn as_fd(&self) -> BorrowedFd<'_> {
17        unsafe { BorrowedFd::borrow_raw(self.0) }
18    }
19}
20
21impl AsRawFd for StaticFd {
22    fn as_raw_fd(&self) -> RawFd {
23        self.0 as _
24    }
25}
26
27/// A handle to the standard input stream of a process.
28///
29/// See [`stdin`].
30#[derive(Debug, Clone)]
31pub struct Stdin(AsyncFd<StaticFd>);
32
33impl Stdin {
34    pub(crate) fn new() -> Self {
35        // SAFETY: no need to attach on unix
36        Self(unsafe { AsyncFd::new_unchecked(StaticFd(libc::STDIN_FILENO)) })
37    }
38}
39
40impl AsyncRead for Stdin {
41    async fn read<B: IoBufMut>(&mut self, buf: B) -> BufResult<usize, B> {
42        (&*self).read(buf).await
43    }
44
45    async fn read_vectored<V: IoVectoredBufMut>(&mut self, buf: V) -> BufResult<usize, V> {
46        (&*self).read_vectored(buf).await
47    }
48}
49
50impl AsyncRead for &Stdin {
51    async fn read<B: IoBufMut>(&mut self, buf: B) -> BufResult<usize, B> {
52        (&self.0).read(buf).await
53    }
54
55    async fn read_vectored<V: IoVectoredBufMut>(&mut self, buf: V) -> BufResult<usize, V> {
56        (&self.0).read_vectored(buf).await
57    }
58}
59
60impl AsyncReadManaged for Stdin {
61    type Buffer<'a> = BorrowedBuffer<'a>;
62    type BufferPool = BufferPool;
63
64    async fn read_managed<'a>(
65        &mut self,
66        buffer_pool: &'a Self::BufferPool,
67        len: usize,
68    ) -> io::Result<Self::Buffer<'a>> {
69        (&*self).read_managed(buffer_pool, len).await
70    }
71}
72
73impl AsyncReadManaged for &Stdin {
74    type Buffer<'a> = BorrowedBuffer<'a>;
75    type BufferPool = BufferPool;
76
77    async fn read_managed<'a>(
78        &mut self,
79        buffer_pool: &'a Self::BufferPool,
80        len: usize,
81    ) -> io::Result<Self::Buffer<'a>> {
82        (&self.0).read_managed(buffer_pool, len).await
83    }
84}
85
86impl AsRawFd for Stdin {
87    fn as_raw_fd(&self) -> RawFd {
88        self.0.as_raw_fd()
89    }
90}
91
92/// A handle to the standard output stream of a process.
93///
94/// See [`stdout`].
95#[derive(Debug, Clone)]
96pub struct Stdout(AsyncFd<StaticFd>);
97
98impl Stdout {
99    pub(crate) fn new() -> Self {
100        // SAFETY: no need to attach on unix
101        Self(unsafe { AsyncFd::new_unchecked(StaticFd(libc::STDOUT_FILENO)) })
102    }
103}
104
105impl AsyncWrite for Stdout {
106    async fn write<T: IoBuf>(&mut self, buf: T) -> BufResult<usize, T> {
107        self.0.write(buf).await
108    }
109
110    async fn write_vectored<T: IoVectoredBuf>(&mut self, buf: T) -> BufResult<usize, T> {
111        self.0.write_vectored(buf).await
112    }
113
114    async fn flush(&mut self) -> io::Result<()> {
115        self.0.flush().await
116    }
117
118    async fn shutdown(&mut self) -> io::Result<()> {
119        self.0.shutdown().await
120    }
121}
122
123impl AsRawFd for Stdout {
124    fn as_raw_fd(&self) -> RawFd {
125        self.0.as_raw_fd()
126    }
127}
128
129/// A handle to the standard output stream of a process.
130///
131/// See [`stderr`].
132#[derive(Debug, Clone)]
133pub struct Stderr(AsyncFd<StaticFd>);
134
135impl Stderr {
136    pub(crate) fn new() -> Self {
137        // SAFETY: no need to attach on unix
138        Self(unsafe { AsyncFd::new_unchecked(StaticFd(libc::STDERR_FILENO)) })
139    }
140}
141
142impl AsyncWrite for Stderr {
143    async fn write<T: IoBuf>(&mut self, buf: T) -> BufResult<usize, T> {
144        self.0.write(buf).await
145    }
146
147    async fn write_vectored<T: IoVectoredBuf>(&mut self, buf: T) -> BufResult<usize, T> {
148        self.0.write_vectored(buf).await
149    }
150
151    async fn flush(&mut self) -> io::Result<()> {
152        self.0.flush().await
153    }
154
155    async fn shutdown(&mut self) -> io::Result<()> {
156        self.0.shutdown().await
157    }
158}
159
160impl AsRawFd for Stderr {
161    fn as_raw_fd(&self) -> RawFd {
162        self.0.as_raw_fd()
163    }
164}