]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/wasi/fd.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / libstd / sys / wasi / fd.rs
1 #![allow(dead_code)]
2
3 use super::err2io;
4 use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
5 use crate::mem;
6 use crate::net::Shutdown;
7
8 #[derive(Debug)]
9 pub struct WasiFd {
10 fd: wasi::Fd,
11 }
12
13 fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
14 assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>());
15 assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>());
16 /// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
17 unsafe {
18 mem::transmute(a)
19 }
20 }
21
22 fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
23 assert_eq!(mem::size_of::<IoSlice<'_>>(), mem::size_of::<wasi::Ciovec>());
24 assert_eq!(mem::align_of::<IoSlice<'_>>(), mem::align_of::<wasi::Ciovec>());
25 /// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
26 unsafe {
27 mem::transmute(a)
28 }
29 }
30
31 impl WasiFd {
32 pub unsafe fn from_raw(fd: wasi::Fd) -> WasiFd {
33 WasiFd { fd }
34 }
35
36 pub fn into_raw(self) -> wasi::Fd {
37 let ret = self.fd;
38 mem::forget(self);
39 ret
40 }
41
42 pub fn as_raw(&self) -> wasi::Fd {
43 self.fd
44 }
45
46 pub fn datasync(&self) -> io::Result<()> {
47 unsafe { wasi::fd_datasync(self.fd).map_err(err2io) }
48 }
49
50 pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
51 unsafe { wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) }
52 }
53
54 pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
55 unsafe { wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) }
56 }
57
58 pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
59 unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) }
60 }
61
62 pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
63 unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) }
64 }
65
66 pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
67 let (whence, offset) = match pos {
68 SeekFrom::Start(pos) => (wasi::WHENCE_SET, pos as i64),
69 SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
70 SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
71 };
72 unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) }
73 }
74
75 pub fn tell(&self) -> io::Result<u64> {
76 unsafe { wasi::fd_tell(self.fd).map_err(err2io) }
77 }
78
79 // FIXME: __wasi_fd_fdstat_get
80
81 pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> {
82 unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) }
83 }
84
85 pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
86 unsafe { wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) }
87 }
88
89 pub fn sync(&self) -> io::Result<()> {
90 unsafe { wasi::fd_sync(self.fd).map_err(err2io) }
91 }
92
93 pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
94 unsafe { wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) }
95 }
96
97 pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
98 unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) }
99 }
100
101 pub fn create_directory(&self, path: &str) -> io::Result<()> {
102 unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) }
103 }
104
105 pub fn link(
106 &self,
107 old_flags: wasi::Lookupflags,
108 old_path: &str,
109 new_fd: &WasiFd,
110 new_path: &str,
111 ) -> io::Result<()> {
112 unsafe {
113 wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path).map_err(err2io)
114 }
115 }
116
117 pub fn open(
118 &self,
119 dirflags: wasi::Lookupflags,
120 path: &str,
121 oflags: wasi::Oflags,
122 fs_rights_base: wasi::Rights,
123 fs_rights_inheriting: wasi::Rights,
124 fs_flags: wasi::Fdflags,
125 ) -> io::Result<WasiFd> {
126 unsafe {
127 wasi::path_open(
128 self.fd,
129 dirflags,
130 path,
131 oflags,
132 fs_rights_base,
133 fs_rights_inheriting,
134 fs_flags,
135 )
136 .map(|fd| WasiFd::from_raw(fd))
137 .map_err(err2io)
138 }
139 }
140
141 pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result<usize> {
142 unsafe { wasi::fd_readdir(self.fd, buf.as_mut_ptr(), buf.len(), cookie).map_err(err2io) }
143 }
144
145 pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result<usize> {
146 unsafe { wasi::path_readlink(self.fd, path, buf.as_mut_ptr(), buf.len()).map_err(err2io) }
147 }
148
149 pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> {
150 unsafe { wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) }
151 }
152
153 pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
154 unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) }
155 }
156
157 pub fn filestat_set_times(
158 &self,
159 atim: wasi::Timestamp,
160 mtim: wasi::Timestamp,
161 fstflags: wasi::Fstflags,
162 ) -> io::Result<()> {
163 unsafe { wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io) }
164 }
165
166 pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
167 unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) }
168 }
169
170 pub fn path_filestat_get(
171 &self,
172 flags: wasi::Lookupflags,
173 path: &str,
174 ) -> io::Result<wasi::Filestat> {
175 unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) }
176 }
177
178 pub fn path_filestat_set_times(
179 &self,
180 flags: wasi::Lookupflags,
181 path: &str,
182 atim: wasi::Timestamp,
183 mtim: wasi::Timestamp,
184 fstflags: wasi::Fstflags,
185 ) -> io::Result<()> {
186 unsafe {
187 wasi::path_filestat_set_times(self.fd, flags, path, atim, mtim, fstflags)
188 .map_err(err2io)
189 }
190 }
191
192 pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> {
193 unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) }
194 }
195
196 pub fn unlink_file(&self, path: &str) -> io::Result<()> {
197 unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) }
198 }
199
200 pub fn remove_directory(&self, path: &str) -> io::Result<()> {
201 unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) }
202 }
203
204 pub fn sock_recv(
205 &self,
206 ri_data: &mut [IoSliceMut<'_>],
207 ri_flags: wasi::Riflags,
208 ) -> io::Result<(usize, wasi::Roflags)> {
209 unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) }
210 }
211
212 pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result<usize> {
213 unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) }
214 }
215
216 pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
217 let how = match how {
218 Shutdown::Read => wasi::SDFLAGS_RD,
219 Shutdown::Write => wasi::SDFLAGS_WR,
220 Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD,
221 };
222 unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) }
223 }
224 }
225
226 impl Drop for WasiFd {
227 fn drop(&mut self) {
228 // FIXME: can we handle the return code here even though we can't on
229 // unix?
230 let _ = unsafe { wasi::fd_close(self.fd) };
231 }
232 }