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,37 +0,0 @@
#![allow(non_camel_case_types)]
use crate::{winerror, Result};
use std::os::windows::prelude::RawHandle;
use winapi::shared::minwindef::FALSE;
pub fn dup(old_handle: RawHandle) -> Result<RawHandle> {
use winapi::um::handleapi::DuplicateHandle;
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::winnt::DUPLICATE_SAME_ACCESS;
unsafe {
let mut new_handle = 0 as RawHandle;
let cur_proc = GetCurrentProcess();
if DuplicateHandle(
cur_proc,
old_handle,
cur_proc,
&mut new_handle,
0, // dwDesiredAccess; this flag is ignored if DUPLICATE_SAME_ACCESS is specified
FALSE,
DUPLICATE_SAME_ACCESS,
) == FALSE
{
Err(winerror::WinError::last())
} else {
Ok(new_handle)
}
}
}
pub fn close(handle: RawHandle) -> Result<()> {
use winapi::um::handleapi::CloseHandle;
if unsafe { CloseHandle(handle) } == FALSE {
Err(winerror::WinError::last())
} else {
Ok(())
}
}

View File

@@ -1,112 +0,0 @@
use crate::{winerror, Result};
use std::marker::PhantomData;
use std::os::windows::prelude::*;
use winapi::shared::{ntdef, ws2def};
// these will be obsolete once https://github.com/rust-lang/rust/pull/60334
// lands in stable
pub struct IoVec<'a> {
vec: ws2def::WSABUF,
_p: PhantomData<&'a [u8]>,
}
impl<'a> IoVec<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> Self {
Self {
vec: ws2def::WSABUF {
len: buf.len() as ntdef::ULONG,
buf: buf.as_ptr() as *mut u8 as *mut ntdef::CHAR,
},
_p: PhantomData,
}
}
#[inline]
pub fn as_slice(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.vec.buf as *const u8, self.vec.len as usize) }
}
}
pub struct IoVecMut<'a> {
vec: ws2def::WSABUF,
_p: PhantomData<&'a mut [u8]>,
}
impl<'a> IoVecMut<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> Self {
Self {
vec: ws2def::WSABUF {
len: buf.len() as ntdef::ULONG,
buf: buf.as_ptr() as *mut u8 as *mut ntdef::CHAR,
},
_p: PhantomData,
}
}
#[inline]
pub fn as_slice(&'a self) -> &'a [u8] {
unsafe { std::slice::from_raw_parts(self.vec.buf as *const u8, self.vec.len as usize) }
}
#[inline]
pub fn as_mut_slice(&'a mut self) -> &'a mut [u8] {
unsafe { std::slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.len as usize) }
}
}
pub fn writev<'a>(raw_handle: RawHandle, iovecs: &'a [IoVec<'a>]) -> Result<usize> {
use winapi::shared::minwindef::{DWORD, FALSE, LPVOID};
use winapi::um::fileapi::WriteFile;
let buf = iovecs
.iter()
.find(|b| !b.as_slice().is_empty())
.map_or(&[][..], |b| b.as_slice());
let mut host_nwritten = 0;
let len = std::cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD;
unsafe {
if WriteFile(
raw_handle,
buf.as_ptr() as LPVOID,
len,
&mut host_nwritten,
std::ptr::null_mut(),
) == FALSE
{
return Err(winerror::WinError::last());
}
}
Ok(host_nwritten as usize)
}
pub fn readv<'a>(raw_handle: RawHandle, iovecs: &'a mut [IoVecMut<'a>]) -> Result<usize> {
use winapi::shared::minwindef::{DWORD, FALSE, LPVOID};
use winapi::um::fileapi::ReadFile;
let buf = iovecs
.iter_mut()
.find(|b| !b.as_slice().is_empty())
.map_or(&mut [][..], |b| b.as_mut_slice());
let mut host_nread = 0;
let len = std::cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD;
unsafe {
if ReadFile(
raw_handle,
buf.as_mut_ptr() as LPVOID,
len,
&mut host_nread,
std::ptr::null_mut(),
) == FALSE
{
return Err(winerror::WinError::last());
}
}
Ok(host_nread as usize)
}

View File

@@ -24,8 +24,6 @@
extern crate bitflags;
pub mod file;
pub mod handle;
pub mod io;
pub mod winerror;
use winerror::WinError;