blob: 9a8b2a0be5b000bb9253e93eaabddbfeb60f9912 [file] [log] [blame]
ThiƩbaud Weksteen3b664ca2020-11-26 14:41:59 +01001#![deny(unsafe_op_in_unsafe_fn)]
Inna Palantff3f07a2019-07-11 16:15:26 -07002#![allow(dead_code)]
3
Matthew Maurerf4d8f812020-03-27 13:14:30 -07004use super::err2io;
Charisee635618d2023-06-01 20:46:00 +00005use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
Inna Palantff3f07a2019-07-11 16:15:26 -07006use crate::mem;
7use crate::net::Shutdown;
Chris Wailesbcf972c2021-10-21 11:03:28 -07008use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
9use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
Inna Palantff3f07a2019-07-11 16:15:26 -070010
11#[derive(Debug)]
12pub struct WasiFd {
Chris Wailesbcf972c2021-10-21 11:03:28 -070013 fd: OwnedFd,
Inna Palantff3f07a2019-07-11 16:15:26 -070014}
15
Matthew Maurerf4d8f812020-03-27 13:14:30 -070016fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
17 assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>());
18 assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>());
Matthew Maurer15a65602020-04-24 14:05:21 -070019 // SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
20 unsafe { mem::transmute(a) }
Inna Palantff3f07a2019-07-11 16:15:26 -070021}
22
Matthew Maurerf4d8f812020-03-27 13:14:30 -070023fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
24 assert_eq!(mem::size_of::<IoSlice<'_>>(), mem::size_of::<wasi::Ciovec>());
25 assert_eq!(mem::align_of::<IoSlice<'_>>(), mem::align_of::<wasi::Ciovec>());
Matthew Maurer15a65602020-04-24 14:05:21 -070026 // SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
27 unsafe { mem::transmute(a) }
Inna Palantff3f07a2019-07-11 16:15:26 -070028}
29
30impl WasiFd {
Inna Palantff3f07a2019-07-11 16:15:26 -070031 pub fn datasync(&self) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070032 unsafe { wasi::fd_datasync(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -070033 }
34
Chih-Hung Hsiehfd666f22019-12-19 14:34:18 -080035 pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070036 unsafe { wasi::fd_pread(self.as_raw_fd() as wasi::Fd, iovec(bufs), offset).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -070037 }
38
Chih-Hung Hsiehfd666f22019-12-19 14:34:18 -080039 pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070040 unsafe {
41 wasi::fd_pwrite(self.as_raw_fd() as wasi::Fd, ciovec(bufs), offset).map_err(err2io)
42 }
Inna Palantff3f07a2019-07-11 16:15:26 -070043 }
44
Chih-Hung Hsiehfd666f22019-12-19 14:34:18 -080045 pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070046 unsafe { wasi::fd_read(self.as_raw_fd() as wasi::Fd, iovec(bufs)).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -070047 }
48
Charisee635618d2023-06-01 20:46:00 +000049 pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
50 unsafe {
51 let bufs = [wasi::Iovec {
52 buf: buf.as_mut().as_mut_ptr() as *mut u8,
53 buf_len: buf.capacity(),
54 }];
55 match wasi::fd_read(self.as_raw_fd() as wasi::Fd, &bufs) {
56 Ok(n) => {
57 buf.advance(n);
58 Ok(())
59 }
60 Err(e) => Err(err2io(e)),
61 }
62 }
63 }
64
Chih-Hung Hsiehfd666f22019-12-19 14:34:18 -080065 pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070066 unsafe { wasi::fd_write(self.as_raw_fd() as wasi::Fd, ciovec(bufs)).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -070067 }
68
69 pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
70 let (whence, offset) = match pos {
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -080071 SeekFrom::Start(pos) => (wasi::WHENCE_SET, pos as i64),
72 SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
73 SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
Inna Palantff3f07a2019-07-11 16:15:26 -070074 };
Chris Wailesbcf972c2021-10-21 11:03:28 -070075 unsafe { wasi::fd_seek(self.as_raw_fd() as wasi::Fd, offset, whence).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -070076 }
77
78 pub fn tell(&self) -> io::Result<u64> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070079 unsafe { wasi::fd_tell(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -070080 }
81
82 // FIXME: __wasi_fd_fdstat_get
83
Matthew Maurerf4d8f812020-03-27 13:14:30 -070084 pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070085 unsafe { wasi::fd_fdstat_set_flags(self.as_raw_fd() as wasi::Fd, flags).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -070086 }
87
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -080088 pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070089 unsafe {
90 wasi::fd_fdstat_set_rights(self.as_raw_fd() as wasi::Fd, base, inheriting)
91 .map_err(err2io)
92 }
Inna Palantff3f07a2019-07-11 16:15:26 -070093 }
94
95 pub fn sync(&self) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -070096 unsafe { wasi::fd_sync(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -070097 }
98
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -080099 pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700100 unsafe {
101 wasi::fd_advise(self.as_raw_fd() as wasi::Fd, offset, len, advice).map_err(err2io)
102 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700103 }
104
105 pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700106 unsafe { wasi::fd_allocate(self.as_raw_fd() as wasi::Fd, offset, len).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -0700107 }
108
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700109 pub fn create_directory(&self, path: &str) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700110 unsafe { wasi::path_create_directory(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -0700111 }
112
113 pub fn link(
114 &self,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700115 old_flags: wasi::Lookupflags,
116 old_path: &str,
Inna Palantff3f07a2019-07-11 16:15:26 -0700117 new_fd: &WasiFd,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700118 new_path: &str,
Inna Palantff3f07a2019-07-11 16:15:26 -0700119 ) -> io::Result<()> {
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800120 unsafe {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700121 wasi::path_link(
122 self.as_raw_fd() as wasi::Fd,
123 old_flags,
124 old_path,
125 new_fd.as_raw_fd() as wasi::Fd,
126 new_path,
127 )
128 .map_err(err2io)
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800129 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700130 }
131
132 pub fn open(
133 &self,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700134 dirflags: wasi::Lookupflags,
135 path: &str,
136 oflags: wasi::Oflags,
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800137 fs_rights_base: wasi::Rights,
138 fs_rights_inheriting: wasi::Rights,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700139 fs_flags: wasi::Fdflags,
Inna Palantff3f07a2019-07-11 16:15:26 -0700140 ) -> io::Result<WasiFd> {
141 unsafe {
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800142 wasi::path_open(
Chris Wailesbcf972c2021-10-21 11:03:28 -0700143 self.as_raw_fd() as wasi::Fd,
Inna Palantff3f07a2019-07-11 16:15:26 -0700144 dirflags,
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800145 path,
Inna Palantff3f07a2019-07-11 16:15:26 -0700146 oflags,
147 fs_rights_base,
148 fs_rights_inheriting,
149 fs_flags,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700150 )
Chris Wailesbcf972c2021-10-21 11:03:28 -0700151 .map(|fd| WasiFd::from_raw_fd(fd as RawFd))
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700152 .map_err(err2io)
Inna Palantff3f07a2019-07-11 16:15:26 -0700153 }
154 }
155
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700156 pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result<usize> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700157 unsafe {
158 wasi::fd_readdir(self.as_raw_fd() as wasi::Fd, buf.as_mut_ptr(), buf.len(), cookie)
159 .map_err(err2io)
160 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700161 }
162
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700163 pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result<usize> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700164 unsafe {
165 wasi::path_readlink(self.as_raw_fd() as wasi::Fd, path, buf.as_mut_ptr(), buf.len())
166 .map_err(err2io)
167 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700168 }
169
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700170 pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700171 unsafe {
172 wasi::path_rename(
173 self.as_raw_fd() as wasi::Fd,
174 old_path,
175 new_fd.as_raw_fd() as wasi::Fd,
176 new_path,
177 )
178 .map_err(err2io)
179 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700180 }
181
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700182 pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700183 unsafe { wasi::fd_filestat_get(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -0700184 }
185
186 pub fn filestat_set_times(
187 &self,
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800188 atim: wasi::Timestamp,
189 mtim: wasi::Timestamp,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700190 fstflags: wasi::Fstflags,
Inna Palantff3f07a2019-07-11 16:15:26 -0700191 ) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700192 unsafe {
193 wasi::fd_filestat_set_times(self.as_raw_fd() as wasi::Fd, atim, mtim, fstflags)
194 .map_err(err2io)
195 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700196 }
197
198 pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700199 unsafe { wasi::fd_filestat_set_size(self.as_raw_fd() as wasi::Fd, size).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -0700200 }
201
202 pub fn path_filestat_get(
203 &self,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700204 flags: wasi::Lookupflags,
205 path: &str,
206 ) -> io::Result<wasi::Filestat> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700207 unsafe {
208 wasi::path_filestat_get(self.as_raw_fd() as wasi::Fd, flags, path).map_err(err2io)
209 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700210 }
211
212 pub fn path_filestat_set_times(
213 &self,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700214 flags: wasi::Lookupflags,
215 path: &str,
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800216 atim: wasi::Timestamp,
217 mtim: wasi::Timestamp,
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700218 fstflags: wasi::Fstflags,
Inna Palantff3f07a2019-07-11 16:15:26 -0700219 ) -> io::Result<()> {
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800220 unsafe {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700221 wasi::path_filestat_set_times(
222 self.as_raw_fd() as wasi::Fd,
223 flags,
224 path,
225 atim,
226 mtim,
227 fstflags,
228 )
229 .map_err(err2io)
Chih-Hung Hsieh8cd2c992019-12-19 15:08:11 -0800230 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700231 }
232
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700233 pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700234 unsafe {
235 wasi::path_symlink(old_path, self.as_raw_fd() as wasi::Fd, new_path).map_err(err2io)
236 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700237 }
238
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700239 pub fn unlink_file(&self, path: &str) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700240 unsafe { wasi::path_unlink_file(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -0700241 }
242
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700243 pub fn remove_directory(&self, path: &str) -> io::Result<()> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700244 unsafe { wasi::path_remove_directory(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -0700245 }
246
Chris Wailes2805eef2022-04-07 11:22:56 -0700247 pub fn sock_accept(&self, flags: wasi::Fdflags) -> io::Result<wasi::Fd> {
248 unsafe { wasi::sock_accept(self.as_raw_fd() as wasi::Fd, flags).map_err(err2io) }
249 }
250
Inna Palantff3f07a2019-07-11 16:15:26 -0700251 pub fn sock_recv(
252 &self,
Chih-Hung Hsiehfd666f22019-12-19 14:34:18 -0800253 ri_data: &mut [IoSliceMut<'_>],
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700254 ri_flags: wasi::Riflags,
255 ) -> io::Result<(usize, wasi::Roflags)> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700256 unsafe {
257 wasi::sock_recv(self.as_raw_fd() as wasi::Fd, iovec(ri_data), ri_flags).map_err(err2io)
258 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700259 }
260
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700261 pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result<usize> {
Chris Wailesbcf972c2021-10-21 11:03:28 -0700262 unsafe {
263 wasi::sock_send(self.as_raw_fd() as wasi::Fd, ciovec(si_data), si_flags).map_err(err2io)
264 }
Inna Palantff3f07a2019-07-11 16:15:26 -0700265 }
266
267 pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
268 let how = match how {
Matthew Maurerf4d8f812020-03-27 13:14:30 -0700269 Shutdown::Read => wasi::SDFLAGS_RD,
270 Shutdown::Write => wasi::SDFLAGS_WR,
271 Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD,
Inna Palantff3f07a2019-07-11 16:15:26 -0700272 };
Chris Wailesbcf972c2021-10-21 11:03:28 -0700273 unsafe { wasi::sock_shutdown(self.as_raw_fd() as wasi::Fd, how).map_err(err2io) }
Inna Palantff3f07a2019-07-11 16:15:26 -0700274 }
275}
276
Chris Wailesbcf972c2021-10-21 11:03:28 -0700277impl AsInner<OwnedFd> for WasiFd {
Chris Wailescd1aefd2023-07-13 13:36:21 -0700278 #[inline]
Chris Wailesbcf972c2021-10-21 11:03:28 -0700279 fn as_inner(&self) -> &OwnedFd {
280 &self.fd
281 }
282}
283
284impl AsInnerMut<OwnedFd> for WasiFd {
Chris Wailescd1aefd2023-07-13 13:36:21 -0700285 #[inline]
Chris Wailesbcf972c2021-10-21 11:03:28 -0700286 fn as_inner_mut(&mut self) -> &mut OwnedFd {
287 &mut self.fd
288 }
289}
290
291impl IntoInner<OwnedFd> for WasiFd {
292 fn into_inner(self) -> OwnedFd {
293 self.fd
294 }
295}
296
297impl FromInner<OwnedFd> for WasiFd {
298 fn from_inner(owned_fd: OwnedFd) -> Self {
299 Self { fd: owned_fd }
300 }
301}
302
303impl AsFd for WasiFd {
304 fn as_fd(&self) -> BorrowedFd<'_> {
305 self.fd.as_fd()
306 }
307}
308
309impl AsRawFd for WasiFd {
Chris Wailescd1aefd2023-07-13 13:36:21 -0700310 #[inline]
Chris Wailesbcf972c2021-10-21 11:03:28 -0700311 fn as_raw_fd(&self) -> RawFd {
312 self.fd.as_raw_fd()
313 }
314}
315
316impl IntoRawFd for WasiFd {
317 fn into_raw_fd(self) -> RawFd {
318 self.fd.into_raw_fd()
319 }
320}
321
322impl FromRawFd for WasiFd {
323 unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
324 unsafe { Self { fd: FromRawFd::from_raw_fd(raw_fd) } }
Inna Palantff3f07a2019-07-11 16:15:26 -0700325 }
326}