use crate::ptr::{Array, WasmPtr};
use crate::syscalls;
use crate::syscalls::types::{self, snapshot0};
use crate::WasiEnv;
pub fn fd_filestat_get(
env: &WasiEnv,
fd: types::__wasi_fd_t,
buf: WasmPtr<snapshot0::__wasi_filestat_t>,
) -> types::__wasi_errno_t {
let memory = env.memory();
let new_buf: WasmPtr<types::__wasi_filestat_t> = unsafe { std::mem::transmute(buf) };
#[allow(clippy::clone_on_copy)]
let new_filestat_setup: types::__wasi_filestat_t =
wasi_try!(new_buf.deref(memory)).get().clone();
let result = syscalls::fd_filestat_get(env, fd, new_buf);
let memory = env.memory();
let new_filestat = wasi_try!(new_buf.deref(memory)).get();
let old_stat = snapshot0::__wasi_filestat_t {
st_dev: new_filestat.st_dev,
st_ino: new_filestat.st_ino,
st_filetype: new_filestat.st_filetype,
st_nlink: new_filestat.st_nlink as u32,
st_size: new_filestat.st_size,
st_atim: new_filestat.st_atim,
st_mtim: new_filestat.st_mtim,
st_ctim: new_filestat.st_ctim,
};
wasi_try!(new_buf.deref(memory)).set(new_filestat_setup);
wasi_try!(buf.deref(memory)).set(old_stat);
result
}
pub fn path_filestat_get(
env: &WasiEnv,
fd: types::__wasi_fd_t,
flags: types::__wasi_lookupflags_t,
path: WasmPtr<u8, Array>,
path_len: u32,
buf: WasmPtr<snapshot0::__wasi_filestat_t>,
) -> types::__wasi_errno_t {
let memory = env.memory();
let new_buf: WasmPtr<types::__wasi_filestat_t> = unsafe { std::mem::transmute(buf) };
#[allow(clippy::clone_on_copy)]
let new_filestat_setup: types::__wasi_filestat_t =
wasi_try!(new_buf.deref(memory)).get().clone();
let result = syscalls::path_filestat_get(env, fd, flags, path, path_len, new_buf);
let memory = env.memory();
let new_filestat = wasi_try!(new_buf.deref(memory)).get();
let old_stat = snapshot0::__wasi_filestat_t {
st_dev: new_filestat.st_dev,
st_ino: new_filestat.st_ino,
st_filetype: new_filestat.st_filetype,
st_nlink: new_filestat.st_nlink as u32,
st_size: new_filestat.st_size,
st_atim: new_filestat.st_atim,
st_mtim: new_filestat.st_mtim,
st_ctim: new_filestat.st_ctim,
};
wasi_try!(new_buf.deref(memory)).set(new_filestat_setup);
wasi_try!(buf.deref(memory)).set(old_stat);
result
}
pub fn fd_seek(
env: &WasiEnv,
fd: types::__wasi_fd_t,
offset: types::__wasi_filedelta_t,
whence: snapshot0::__wasi_whence_t,
newoffset: WasmPtr<types::__wasi_filesize_t>,
) -> types::__wasi_errno_t {
let new_whence = match whence {
snapshot0::__WASI_WHENCE_CUR => types::__WASI_WHENCE_CUR,
snapshot0::__WASI_WHENCE_END => types::__WASI_WHENCE_END,
snapshot0::__WASI_WHENCE_SET => types::__WASI_WHENCE_SET,
_ => whence,
};
syscalls::fd_seek(env, fd, offset, new_whence, newoffset)
}
pub fn poll_oneoff(
env: &WasiEnv,
in_: WasmPtr<snapshot0::__wasi_subscription_t, Array>,
out_: WasmPtr<types::__wasi_event_t, Array>,
nsubscriptions: u32,
nevents: WasmPtr<u32>,
) -> types::__wasi_errno_t {
let memory = env.memory();
let mut in_origs: Vec<snapshot0::__wasi_subscription_t> = vec![];
for in_sub in wasi_try!(in_.deref(memory, 0, nsubscriptions)) {
in_origs.push(in_sub.get());
}
let in_new_type_ptr: WasmPtr<types::__wasi_subscription_t, Array> =
unsafe { std::mem::transmute(in_) };
for (in_sub_new, orig) in wasi_try!(in_new_type_ptr.deref(memory, 0, nsubscriptions))
.iter()
.zip(in_origs.iter())
{
in_sub_new.set(types::__wasi_subscription_t {
userdata: orig.userdata,
type_: orig.type_,
u: if orig.type_ == types::__WASI_EVENTTYPE_CLOCK {
types::__wasi_subscription_u {
clock: types::__wasi_subscription_clock_t {
clock_id: unsafe { orig.u.clock.clock_id },
timeout: unsafe { orig.u.clock.timeout },
precision: unsafe { orig.u.clock.precision },
flags: unsafe { orig.u.clock.flags },
},
}
} else {
types::__wasi_subscription_u {
fd_readwrite: unsafe { orig.u.fd_readwrite },
}
},
});
}
let result = syscalls::poll_oneoff(env, in_new_type_ptr, out_, nsubscriptions, nevents);
let memory = env.memory();
for (in_sub, orig) in wasi_try!(in_.deref(memory, 0, nsubscriptions))
.iter()
.zip(in_origs.into_iter())
{
in_sub.set(orig);
}
result
}