4 use crate::io
::{self, IoSlice, IoSliceMut, SeekFrom}
;
6 use crate::net
::Shutdown
;
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
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
32 pub unsafe fn from_raw(fd
: wasi
::Fd
) -> WasiFd
{
36 pub fn into_raw(self) -> wasi
::Fd
{
42 pub fn as_raw(&self) -> wasi
::Fd
{
46 pub fn datasync(&self) -> io
::Result
<()> {
47 unsafe { wasi::fd_datasync(self.fd).map_err(err2io) }
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) }
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) }
58 pub fn read(&self, bufs
: &mut [IoSliceMut
<'_
>]) -> io
::Result
<usize> {
59 unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) }
62 pub fn write(&self, bufs
: &[IoSlice
<'_
>]) -> io
::Result
<usize> {
63 unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) }
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
),
72 unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) }
75 pub fn tell(&self) -> io
::Result
<u64> {
76 unsafe { wasi::fd_tell(self.fd).map_err(err2io) }
79 // FIXME: __wasi_fd_fdstat_get
81 pub fn set_flags(&self, flags
: wasi
::Fdflags
) -> io
::Result
<()> {
82 unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) }
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) }
89 pub fn sync(&self) -> io
::Result
<()> {
90 unsafe { wasi::fd_sync(self.fd).map_err(err2io) }
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) }
97 pub fn allocate(&self, offset
: u64, len
: u64) -> io
::Result
<()> {
98 unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) }
101 pub fn create_directory(&self, path
: &str) -> io
::Result
<()> {
102 unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) }
107 old_flags
: wasi
::Lookupflags
,
111 ) -> io
::Result
<()> {
113 wasi
::path_link(self.fd
, old_flags
, old_path
, new_fd
.fd
, new_path
).map_err(err2io
)
119 dirflags
: wasi
::Lookupflags
,
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
> {
133 fs_rights_inheriting
,
136 .map(|fd
| WasiFd
::from_raw(fd
))
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) }
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) }
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) }
153 pub fn filestat_get(&self) -> io
::Result
<wasi
::Filestat
> {
154 unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) }
157 pub fn filestat_set_times(
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) }
166 pub fn filestat_set_size(&self, size
: u64) -> io
::Result
<()> {
167 unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) }
170 pub fn path_filestat_get(
172 flags
: wasi
::Lookupflags
,
174 ) -> io
::Result
<wasi
::Filestat
> {
175 unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) }
178 pub fn path_filestat_set_times(
180 flags
: wasi
::Lookupflags
,
182 atim
: wasi
::Timestamp
,
183 mtim
: wasi
::Timestamp
,
184 fstflags
: wasi
::Fstflags
,
185 ) -> io
::Result
<()> {
187 wasi
::path_filestat_set_times(self.fd
, flags
, path
, atim
, mtim
, fstflags
)
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) }
196 pub fn unlink_file(&self, path
: &str) -> io
::Result
<()> {
197 unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) }
200 pub fn remove_directory(&self, path
: &str) -> io
::Result
<()> {
201 unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) }
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) }
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) }
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
,
222 unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) }
226 impl Drop
for WasiFd
{
228 // FIXME: can we handle the return code here even though we can't on
230 let _
= unsafe { wasi::fd_close(self.fd) }
;