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:
107
src/fdentry.rs
Normal file
107
src/fdentry.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use super::host;
|
||||
use crate::sys::{errno_from_host, fdentry_impl};
|
||||
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Descriptor {
|
||||
File(fs::File),
|
||||
Stdin,
|
||||
Stdout,
|
||||
Stderr,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FdObject {
|
||||
pub file_type: host::__wasi_filetype_t,
|
||||
pub descriptor: ManuallyDrop<Descriptor>,
|
||||
pub needs_close: bool,
|
||||
// TODO: directories
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FdEntry {
|
||||
pub fd_object: FdObject,
|
||||
pub rights_base: host::__wasi_rights_t,
|
||||
pub rights_inheriting: host::__wasi_rights_t,
|
||||
pub preopen_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Drop for FdObject {
|
||||
fn drop(&mut self) {
|
||||
if self.needs_close {
|
||||
unsafe { ManuallyDrop::drop(&mut self.descriptor) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FdEntry {
|
||||
pub fn from(file: fs::File) -> Result<Self, host::__wasi_errno_t> {
|
||||
fdentry_impl::determine_type_and_access_rights(&file).map(
|
||||
|(file_type, rights_base, rights_inheriting)| Self {
|
||||
fd_object: FdObject {
|
||||
file_type,
|
||||
descriptor: ManuallyDrop::new(Descriptor::File(file)),
|
||||
needs_close: true,
|
||||
},
|
||||
rights_base,
|
||||
rights_inheriting,
|
||||
preopen_path: None,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn duplicate(file: &fs::File) -> Result<Self, host::__wasi_errno_t> {
|
||||
file.try_clone()
|
||||
.map_err(|err| err.raw_os_error().map_or(host::__WASI_EIO, errno_from_host))
|
||||
.and_then(Self::from)
|
||||
}
|
||||
|
||||
pub fn duplicate_stdin() -> Result<Self, host::__wasi_errno_t> {
|
||||
fdentry_impl::determine_type_and_access_rights(&io::stdin()).map(
|
||||
|(file_type, rights_base, rights_inheriting)| Self {
|
||||
fd_object: FdObject {
|
||||
file_type,
|
||||
descriptor: ManuallyDrop::new(Descriptor::Stdin),
|
||||
needs_close: true,
|
||||
},
|
||||
rights_base,
|
||||
rights_inheriting,
|
||||
preopen_path: None,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn duplicate_stdout() -> Result<Self, host::__wasi_errno_t> {
|
||||
fdentry_impl::determine_type_and_access_rights(&io::stdout()).map(
|
||||
|(file_type, rights_base, rights_inheriting)| Self {
|
||||
fd_object: FdObject {
|
||||
file_type,
|
||||
descriptor: ManuallyDrop::new(Descriptor::Stdout),
|
||||
needs_close: true,
|
||||
},
|
||||
rights_base,
|
||||
rights_inheriting,
|
||||
preopen_path: None,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn duplicate_stderr() -> Result<Self, host::__wasi_errno_t> {
|
||||
fdentry_impl::determine_type_and_access_rights(&io::stderr()).map(
|
||||
|(file_type, rights_base, rights_inheriting)| Self {
|
||||
fd_object: FdObject {
|
||||
file_type,
|
||||
descriptor: ManuallyDrop::new(Descriptor::Stderr),
|
||||
needs_close: true,
|
||||
},
|
||||
rights_base,
|
||||
rights_inheriting,
|
||||
preopen_path: None,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user