wasi_common/tokio/
file.rs1use crate::tokio::block_on_dummy_executor;
2use crate::{
3 file::{Advice, FdFlags, FileType, Filestat, WasiFile},
4 Error,
5};
6#[cfg(windows)]
7use io_extras::os::windows::{AsRawHandleOrSocket, RawHandleOrSocket};
8#[cfg(not(windows))]
9use io_lifetimes::AsFd;
10use std::any::Any;
11use std::borrow::Borrow;
12use std::io;
13
14pub struct File(crate::sync::file::File);
15
16impl File {
17 pub(crate) fn from_inner(file: crate::sync::file::File) -> Self {
18 File(file)
19 }
20 pub fn from_cap_std(file: cap_std::fs::File) -> Self {
21 Self::from_inner(crate::sync::file::File::from_cap_std(file))
22 }
23}
24
25pub struct TcpListener(crate::sync::net::TcpListener);
26
27impl TcpListener {
28 pub(crate) fn from_inner(listener: crate::sync::net::TcpListener) -> Self {
29 TcpListener(listener)
30 }
31 pub fn from_cap_std(listener: cap_std::net::TcpListener) -> Self {
32 Self::from_inner(crate::sync::net::TcpListener::from_cap_std(listener))
33 }
34}
35
36pub struct TcpStream(crate::sync::net::TcpStream);
37
38impl TcpStream {
39 pub(crate) fn from_inner(stream: crate::sync::net::TcpStream) -> Self {
40 TcpStream(stream)
41 }
42 pub fn from_cap_std(stream: cap_std::net::TcpStream) -> Self {
43 Self::from_inner(crate::sync::net::TcpStream::from_cap_std(stream))
44 }
45}
46
47#[cfg(unix)]
48pub struct UnixListener(crate::sync::net::UnixListener);
49
50#[cfg(unix)]
51impl UnixListener {
52 pub(crate) fn from_inner(listener: crate::sync::net::UnixListener) -> Self {
53 UnixListener(listener)
54 }
55 pub fn from_cap_std(listener: cap_std::os::unix::net::UnixListener) -> Self {
56 Self::from_inner(crate::sync::net::UnixListener::from_cap_std(listener))
57 }
58}
59
60#[cfg(unix)]
61pub struct UnixStream(crate::sync::net::UnixStream);
62
63#[cfg(unix)]
64impl UnixStream {
65 fn from_inner(stream: crate::sync::net::UnixStream) -> Self {
66 UnixStream(stream)
67 }
68 pub fn from_cap_std(stream: cap_std::os::unix::net::UnixStream) -> Self {
69 Self::from_inner(crate::sync::net::UnixStream::from_cap_std(stream))
70 }
71}
72
73pub struct Stdin(crate::sync::stdio::Stdin);
74
75pub fn stdin() -> Stdin {
76 Stdin(crate::sync::stdio::stdin())
77}
78
79pub struct Stdout(crate::sync::stdio::Stdout);
80
81pub fn stdout() -> Stdout {
82 Stdout(crate::sync::stdio::stdout())
83}
84
85pub struct Stderr(crate::sync::stdio::Stderr);
86
87pub fn stderr() -> Stderr {
88 Stderr(crate::sync::stdio::stderr())
89}
90
91macro_rules! wasi_file_impl {
92 ($ty:ty) => {
93 #[wiggle::async_trait]
94 impl WasiFile for $ty {
95 fn as_any(&self) -> &dyn Any {
96 self
97 }
98 #[cfg(unix)]
99 fn pollable(&self) -> Option<rustix::fd::BorrowedFd> {
100 Some(self.0.as_fd())
101 }
102 #[cfg(windows)]
103 fn pollable(&self) -> Option<io_extras::os::windows::RawHandleOrSocket> {
104 Some(self.0.as_raw_handle_or_socket())
105 }
106 async fn datasync(&self) -> Result<(), Error> {
107 block_on_dummy_executor(|| self.0.datasync())
108 }
109 async fn sync(&self) -> Result<(), Error> {
110 block_on_dummy_executor(|| self.0.sync())
111 }
112 async fn get_filetype(&self) -> Result<FileType, Error> {
113 block_on_dummy_executor(|| self.0.get_filetype())
114 }
115 async fn get_fdflags(&self) -> Result<FdFlags, Error> {
116 block_on_dummy_executor(|| self.0.get_fdflags())
117 }
118 async fn set_fdflags(&mut self, fdflags: FdFlags) -> Result<(), Error> {
119 block_on_dummy_executor(|| self.0.set_fdflags(fdflags))
120 }
121 async fn get_filestat(&self) -> Result<Filestat, Error> {
122 block_on_dummy_executor(|| self.0.get_filestat())
123 }
124 async fn set_filestat_size(&self, size: u64) -> Result<(), Error> {
125 block_on_dummy_executor(move || self.0.set_filestat_size(size))
126 }
127 async fn advise(&self, offset: u64, len: u64, advice: Advice) -> Result<(), Error> {
128 block_on_dummy_executor(move || self.0.advise(offset, len, advice))
129 }
130 async fn read_vectored<'a>(
131 &self,
132 bufs: &mut [io::IoSliceMut<'a>],
133 ) -> Result<u64, Error> {
134 block_on_dummy_executor(move || self.0.read_vectored(bufs))
135 }
136 async fn read_vectored_at<'a>(
137 &self,
138 bufs: &mut [io::IoSliceMut<'a>],
139 offset: u64,
140 ) -> Result<u64, Error> {
141 block_on_dummy_executor(move || self.0.read_vectored_at(bufs, offset))
142 }
143 async fn write_vectored<'a>(&self, bufs: &[io::IoSlice<'a>]) -> Result<u64, Error> {
144 block_on_dummy_executor(move || self.0.write_vectored(bufs))
145 }
146 async fn write_vectored_at<'a>(
147 &self,
148 bufs: &[io::IoSlice<'a>],
149 offset: u64,
150 ) -> Result<u64, Error> {
151 if bufs.iter().map(|i| i.len()).sum::<usize>() == 0 {
152 return Ok(0);
153 }
154 block_on_dummy_executor(move || self.0.write_vectored_at(bufs, offset))
155 }
156 async fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> {
157 block_on_dummy_executor(move || self.0.seek(pos))
158 }
159 async fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> {
160 block_on_dummy_executor(move || self.0.peek(buf))
161 }
162 async fn set_times(
163 &self,
164 atime: Option<crate::SystemTimeSpec>,
165 mtime: Option<crate::SystemTimeSpec>,
166 ) -> Result<(), Error> {
167 block_on_dummy_executor(move || self.0.set_times(atime, mtime))
168 }
169 fn num_ready_bytes(&self) -> Result<u64, Error> {
170 self.0.num_ready_bytes()
171 }
172 fn isatty(&self) -> bool {
173 self.0.isatty()
174 }
175
176 #[cfg(not(windows))]
177 async fn readable(&self) -> Result<(), Error> {
178 use std::os::unix::io::AsRawFd;
184 use tokio::io::{unix::AsyncFd, Interest};
185 let rawfd = self.0.borrow().as_fd().as_raw_fd();
186 match AsyncFd::with_interest(rawfd, Interest::READABLE) {
187 Ok(asyncfd) => {
188 let _ = asyncfd.readable().await?;
189 Ok(())
190 }
191 Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
192 Ok(())
195 }
196 Err(e) => Err(e.into()),
197 }
198 }
199
200 #[cfg(not(windows))]
201 async fn writable(&self) -> Result<(), Error> {
202 use std::os::unix::io::AsRawFd;
208 use tokio::io::{unix::AsyncFd, Interest};
209 let rawfd = self.0.borrow().as_fd().as_raw_fd();
210 match AsyncFd::with_interest(rawfd, Interest::WRITABLE) {
211 Ok(asyncfd) => {
212 let _ = asyncfd.writable().await?;
213 Ok(())
214 }
215 Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
216 Ok(())
219 }
220 Err(e) => Err(e.into()),
221 }
222 }
223
224 async fn sock_accept(&self, fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
225 block_on_dummy_executor(|| self.0.sock_accept(fdflags))
226 }
227 }
228 #[cfg(windows)]
229 impl AsRawHandleOrSocket for $ty {
230 #[inline]
231 fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
232 self.0.borrow().as_raw_handle_or_socket()
233 }
234 }
235 };
236}
237
238wasi_file_impl!(File);
239wasi_file_impl!(TcpListener);
240wasi_file_impl!(TcpStream);
241#[cfg(unix)]
242wasi_file_impl!(UnixListener);
243#[cfg(unix)]
244wasi_file_impl!(UnixStream);
245wasi_file_impl!(Stdin);
246wasi_file_impl!(Stdout);
247wasi_file_impl!(Stderr);