Skip to main content

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