Rewrite majority of impl reusing libstd (#34)

* Rewrite FdEntry reusing as much libstd as possible

* Use the new FdEntry, FdObject, Descriptor struct in *nix impl

* Adapt Windows impl

* Remove unnecessary check in fd_read

Check `host_nread == 0` caused premature FdEntry closure and removal
which ultimately was resulting in an attempt at "double closing" of
the same file descriptor at the end of the Wasm program:
...
fd_close(fd=4)
    -> errno=WASI_ESUCCESS
fd_close(fd=4)
    -> errno=WASI_EBADF

* Use libstd vectored IO

* Use std:🧵:yield_now to implement sched_yield

* Add logging to integration tests

* Add preliminary support for host-specific errors

* Operate on std::fs::File in path_get on *nix

* Add cross-platform RawString type encapsulating OsStrExt

* Fix Windows build

* Update Travis and README to Rust v1.36

* Remove unused winx::handle::close helper

* Refactor Descriptor into raw handles/fds

* Strip readlinkat in prep for path_get host-independent

* Strip openat in prep for path_get host-independent

* Move ManuallyDrop up one level from Descriptor to FdObject

* Make (c)iovec host fns unsafe

* Swap unwraps/expects for Results in fdentry_impl on nix

* Rewrite fd_pread/write and implement for Win

* Use File::sync_all to impl fd_sync

* Use File::sync_data to impl fd_datasync

* Rewind file cursor after fd_p{read, write} on Windows

* Add fd_p{read, write} tests

* Handle errors instead of panicking in path_get

* Use File::set_len to impl fd_allocate

* Add test for fd_allocate

* Replace all panics with Results

* Document the point of RawString
This commit is contained in:
Jakub Konka
2019-07-16 00:34:28 +02:00
committed by Dan Gohman
parent 93e1657bae
commit 667f272edd
32 changed files with 977 additions and 1045 deletions

View File

@@ -1,8 +1,7 @@
#![allow(non_camel_case_types)]
#![allow(unused_unsafe)]
use super::host_impl;
use crate::memory::*;
use crate::sys::host_impl;
use crate::{host, wasm32};
use nix::convert_ioctl_res;
@@ -81,12 +80,13 @@ pub(crate) fn poll_oneoff(
.iter()
.filter_map(|event| match event {
Ok(event) if event.type_ == wasm32::__WASI_EVENTTYPE_CLOCK => Some(ClockEventData {
delay: wasi_clock_to_relative_ns_delay(unsafe { event.u.clock }) / 1_000_000,
delay: wasi_clock_to_relative_ns_delay(unsafe { event.u.clock }).ok()? / 1_000_000,
userdata: event.userdata,
}),
_ => None,
})
.min_by_key(|event| event.delay);
let fd_events: Vec<_> = input
.iter()
.filter_map(|event| match event {
@@ -147,26 +147,21 @@ pub(crate) fn poll_oneoff(
Ok(events_count)
}
pub(crate) fn sched_yield() -> Result<(), host::__wasi_errno_t> {
unsafe { libc::sched_yield() };
Ok(())
}
// define the `fionread()` function, equivalent to `ioctl(fd, FIONREAD, *bytes)`
nix::ioctl_read_bad!(fionread, nix::libc::FIONREAD, c_int);
fn wasi_clock_to_relative_ns_delay(
wasi_clock: host::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_clock_t,
) -> u128 {
) -> Result<u128, host::__wasi_errno_t> {
if wasi_clock.flags != wasm32::__WASI_SUBSCRIPTION_CLOCK_ABSTIME {
return wasi_clock.timeout as u128;
return Ok(wasi_clock.timeout as u128);
}
let now: u128 = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Current date is before the epoch")
.map_err(|_| host::__WASI_ENOTCAPABLE)?
.as_nanos();
let deadline = wasi_clock.timeout as u128;
deadline.saturating_sub(now)
Ok(deadline.saturating_sub(now))
}
#[derive(Debug, Copy, Clone)]