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:
@@ -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(())
|
||||
}
|
||||
}
|
||||
112
winx/src/io.rs
112
winx/src/io.rs
@@ -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)
|
||||
}
|
||||
@@ -24,8 +24,6 @@
|
||||
extern crate bitflags;
|
||||
|
||||
pub mod file;
|
||||
pub mod handle;
|
||||
pub mod io;
|
||||
pub mod winerror;
|
||||
|
||||
use winerror::WinError;
|
||||
|
||||
Reference in New Issue
Block a user