refactor wasi state file to hide boilerplate

This commit is contained in:
Mark McCaskey
2019-08-05 11:59:32 +09:00
parent c2e3847e9a
commit f0eb85a919
3 changed files with 421 additions and 340 deletions

View File

@@ -5,6 +5,10 @@
// vfs::Vfs,
// file_like::{FileLike, Metadata};
// };
mod types;
pub use self::types::*;
use crate::syscalls::types::*;
use generational_arena::Arena;
pub use generational_arena::Index as Inode;
@@ -13,7 +17,7 @@ use std::{
borrow::Borrow,
cell::Cell,
fs,
io::{self, Read, Seek, Write},
io::{self, Write},
path::{Path, PathBuf},
time::SystemTime,
};
@@ -34,332 +38,6 @@ pub unsafe fn get_wasi_state(ctx: &mut Ctx) -> &mut WasiState {
/// the number of symlinks that can be traversed when resolving a path
pub const MAX_SYMLINKS: u32 = 128;
/// Error type for external users
#[derive(Debug, PartialEq, Eq)]
#[allow(dead_code)]
// dead code beacuse this is for external use
pub enum WasiFsError {
/// The fd given as a base was not a directory so the operation was not possible
BaseNotDirectory,
/// Expected a file but found not a file
NotAFile,
/// The fd given was not usable
InvalidFd,
/// File exists
AlreadyExists,
/// Something failed when doing IO. These errors can generally not be handled.
/// It may work if tried again.
IOError,
/// A WASI error without an external name. If you encounter this it means
/// that there's probably a bug on our side (maybe as simple as forgetting to wrap
/// this error, but perhaps something broke)
UnknownError(__wasi_errno_t),
}
impl WasiFsError {
pub fn from_wasi_err(err: __wasi_errno_t) -> WasiFsError {
match err {
__WASI_EBADF => WasiFsError::InvalidFd,
__WASI_EEXIST => WasiFsError::AlreadyExists,
__WASI_EIO => WasiFsError::IOError,
_ => WasiFsError::UnknownError(err),
}
}
}
/// This trait relies on your file closing when it goes out of scope via `Drop`
pub trait WasiFile: std::fmt::Debug + Write + Read + Seek {
/// the last time the file was accessed in nanoseconds as a UNIX timestamp
fn last_accessed(&self) -> __wasi_timestamp_t;
/// the last time the file was modified in nanoseconds as a UNIX timestamp
fn last_modified(&self) -> __wasi_timestamp_t;
/// the time at which the file was created in nanoseconds as a UNIX timestamp
fn created_time(&self) -> __wasi_timestamp_t;
/// set the last time the file was accessed in nanoseconds as a UNIX timestamp
// TODO: stablize this in 0.7.0 by removing default impl
fn set_last_accessed(&self, _last_accessed: __wasi_timestamp_t) {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_last_accessed for your type before then");
}
/// set the last time the file was modified in nanoseconds as a UNIX timestamp
// TODO: stablize this in 0.7.0 by removing default impl
fn set_last_modified(&self, _last_modified: __wasi_timestamp_t) {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_last_modified for your type before then");
}
/// set the time at which the file was created in nanoseconds as a UNIX timestamp
// TODO: stablize this in 0.7.0 by removing default impl
fn set_created_time(&self, _created_time: __wasi_timestamp_t) {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_created_time for your type before then");
}
/// the size of the file in bytes
fn size(&self) -> u64;
/// Change the size of the file, if the `new_size` is greater than the current size
/// the extra bytes will be allocated and zeroed
// TODO: stablize this in 0.7.0 by removing default impl
fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Option<()> {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::allocate for your type before then");
}
}
impl WasiFile for fs::File {
fn last_accessed(&self) -> u64 {
self.metadata()
.unwrap()
.accessed()
.ok()
.and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|ct| ct.as_nanos() as u64)
.unwrap_or(0)
}
fn set_last_accessed(&self, _last_accessed: __wasi_timestamp_t) {
// TODO: figure out how to do this
}
fn last_modified(&self) -> u64 {
self.metadata()
.unwrap()
.modified()
.ok()
.and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|ct| ct.as_nanos() as u64)
.unwrap_or(0)
}
fn set_last_modified(&self, _last_modified: __wasi_timestamp_t) {
// TODO: figure out how to do this
}
fn created_time(&self) -> u64 {
self.metadata()
.unwrap()
.created()
.ok()
.and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|ct| ct.as_nanos() as u64)
.unwrap_or(0)
}
fn set_created_time(&self, _created_time: __wasi_timestamp_t) {
// TODO: figure out how to do this
}
fn size(&self) -> u64 {
self.metadata().unwrap().len()
}
fn set_len(&mut self, new_size: __wasi_filesize_t) -> Option<()> {
fs::File::set_len(self, new_size).ok()
}
}
#[derive(Debug)]
pub struct Stdout(std::io::Stdout);
impl Read for Stdout {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stdout",
))
}
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stdout",
))
}
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stdout",
))
}
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stdout",
))
}
}
impl Seek for Stdout {
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not seek stdout",
))
}
}
impl Write for Stdout {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.0.write_all(buf)
}
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
self.0.write_fmt(fmt)
}
}
impl WasiFile for Stdout {
fn last_accessed(&self) -> u64 {
0
}
fn last_modified(&self) -> u64 {
0
}
fn created_time(&self) -> u64 {
0
}
fn size(&self) -> u64 {
0
}
}
#[derive(Debug)]
pub struct Stderr(std::io::Stderr);
impl Read for Stderr {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stderr",
))
}
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stderr",
))
}
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stderr",
))
}
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stderr",
))
}
}
impl Seek for Stderr {
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not seek stderr",
))
}
}
impl Write for Stderr {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.0.write_all(buf)
}
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
self.0.write_fmt(fmt)
}
}
impl WasiFile for Stderr {
fn last_accessed(&self) -> u64 {
0
}
fn last_modified(&self) -> u64 {
0
}
fn created_time(&self) -> u64 {
0
}
fn size(&self) -> u64 {
0
}
}
#[derive(Debug)]
pub struct Stdin(std::io::Stdin);
impl Read for Stdin {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
self.0.read_to_string(buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.0.read_exact(buf)
}
}
impl Seek for Stdin {
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not seek stdin",
))
}
}
impl Write for Stdin {
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not write to stdin",
))
}
fn flush(&mut self) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not write to stdin",
))
}
fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not write to stdin",
))
}
fn write_fmt(&mut self, _fmt: ::std::fmt::Arguments) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not write to stdin",
))
}
}
impl WasiFile for Stdin {
fn last_accessed(&self) -> u64 {
0
}
fn last_modified(&self) -> u64 {
0
}
fn created_time(&self) -> u64 {
0
}
fn size(&self) -> u64 {
0
}
}
/*
TODO: Think about using this
trait WasiFdBacking: std::fmt::Debug {
fn get_stat(&self) -> &__wasi_filestat_t;
fn get_stat_mut(&mut self) -> &mut __wasi_filestat_t;
fn is_preopened(&self) -> bool;
fn get_name(&self) -> &str;
}
*/
/// A file that Wasi knows about that may or may not be open
#[derive(Debug)]
pub struct InodeVal {

396
lib/wasi/src/state/types.rs Normal file
View File

@@ -0,0 +1,396 @@
/// types for use in the WASI filesystem
use crate::syscalls::types::*;
use std::{
fs,
io::{self, Read, Seek, Write},
path::PathBuf,
time::SystemTime,
};
/// Error type for external users
#[derive(Debug, PartialEq, Eq)]
#[allow(dead_code)]
// dead code beacuse this is for external use
pub enum WasiFsError {
/// The fd given as a base was not a directory so the operation was not possible
BaseNotDirectory,
/// Expected a file but found not a file
NotAFile,
/// The fd given was not usable
InvalidFd,
/// File exists
AlreadyExists,
/// Something failed when doing IO. These errors can generally not be handled.
/// It may work if tried again.
IOError,
/// A WASI error without an external name. If you encounter this it means
/// that there's probably a bug on our side (maybe as simple as forgetting to wrap
/// this error, but perhaps something broke)
UnknownError(__wasi_errno_t),
}
impl WasiFsError {
pub fn from_wasi_err(err: __wasi_errno_t) -> WasiFsError {
match err {
__WASI_EBADF => WasiFsError::InvalidFd,
__WASI_EEXIST => WasiFsError::AlreadyExists,
__WASI_EIO => WasiFsError::IOError,
_ => WasiFsError::UnknownError(err),
}
}
}
/// This trait relies on your file closing when it goes out of scope via `Drop`
pub trait WasiFile: std::fmt::Debug + Write + Read + Seek {
/// the last time the file was accessed in nanoseconds as a UNIX timestamp
fn last_accessed(&self) -> __wasi_timestamp_t;
/// the last time the file was modified in nanoseconds as a UNIX timestamp
fn last_modified(&self) -> __wasi_timestamp_t;
/// the time at which the file was created in nanoseconds as a UNIX timestamp
fn created_time(&self) -> __wasi_timestamp_t;
/// set the last time the file was accessed in nanoseconds as a UNIX timestamp
// TODO: stablize this in 0.7.0 by removing default impl
fn set_last_accessed(&self, _last_accessed: __wasi_timestamp_t) {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_last_accessed for your type before then");
}
/// set the last time the file was modified in nanoseconds as a UNIX timestamp
// TODO: stablize this in 0.7.0 by removing default impl
fn set_last_modified(&self, _last_modified: __wasi_timestamp_t) {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_last_modified for your type before then");
}
/// set the time at which the file was created in nanoseconds as a UNIX timestamp
// TODO: stablize this in 0.7.0 by removing default impl
fn set_created_time(&self, _created_time: __wasi_timestamp_t) {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_created_time for your type before then");
}
/// the size of the file in bytes
fn size(&self) -> u64;
/// Change the size of the file, if the `new_size` is greater than the current size
/// the extra bytes will be allocated and zeroed
// TODO: stablize this in 0.7.0 by removing default impl
fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Option<()> {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::allocate for your type before then");
}
/// Request deletion of the file
// TODO: stablize this in 0.7.0 by removing default impl
fn unlink(&mut self) -> Option<()> {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::unlink for your type before then");
}
}
/// A thin wrapper around `std::fs::File`
#[derive(Debug)]
pub struct HostFile {
pub inner: fs::File,
pub host_path: PathBuf,
}
impl HostFile {
/// creates a new host file from a `std::fs::File` and a path
pub fn new(file: fs::File, host_path: PathBuf) -> Self {
Self {
inner: file,
host_path,
}
}
pub fn metadata(&self) -> fs::Metadata {
self.inner.metadata().unwrap()
}
}
impl Read for HostFile {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.inner.read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
self.inner.read_to_string(buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.inner.read_exact(buf)
}
}
impl Seek for HostFile {
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
}
}
impl Write for HostFile {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.inner.write_all(buf)
}
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
self.inner.write_fmt(fmt)
}
}
impl WasiFile for HostFile {
fn last_accessed(&self) -> u64 {
self.metadata()
.accessed()
.ok()
.and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|ct| ct.as_nanos() as u64)
.unwrap_or(0)
}
fn set_last_accessed(&self, _last_accessed: __wasi_timestamp_t) {
// TODO: figure out how to do this
}
fn last_modified(&self) -> u64 {
self.metadata()
.modified()
.ok()
.and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|ct| ct.as_nanos() as u64)
.unwrap_or(0)
}
fn set_last_modified(&self, _last_modified: __wasi_timestamp_t) {
// TODO: figure out how to do this
}
fn created_time(&self) -> u64 {
self.metadata()
.created()
.ok()
.and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|ct| ct.as_nanos() as u64)
.unwrap_or(0)
}
fn set_created_time(&self, _created_time: __wasi_timestamp_t) {
// TODO: figure out how to do this
}
fn size(&self) -> u64 {
self.metadata().len()
}
fn set_len(&mut self, new_size: __wasi_filesize_t) -> Option<()> {
fs::File::set_len(&self.inner, new_size).ok()
}
fn unlink(&mut self) -> Option<()> {
std::fs::remove_file(&self.host_path).ok()
}
}
#[derive(Debug)]
pub struct Stdout(pub std::io::Stdout);
impl Read for Stdout {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stdout",
))
}
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stdout",
))
}
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stdout",
))
}
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stdout",
))
}
}
impl Seek for Stdout {
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not seek stdout",
))
}
}
impl Write for Stdout {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.0.write_all(buf)
}
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
self.0.write_fmt(fmt)
}
}
impl WasiFile for Stdout {
fn last_accessed(&self) -> u64 {
0
}
fn last_modified(&self) -> u64 {
0
}
fn created_time(&self) -> u64 {
0
}
fn size(&self) -> u64 {
0
}
}
#[derive(Debug)]
pub struct Stderr(pub std::io::Stderr);
impl Read for Stderr {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stderr",
))
}
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stderr",
))
}
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stderr",
))
}
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from stderr",
))
}
}
impl Seek for Stderr {
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not seek stderr",
))
}
}
impl Write for Stderr {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.0.write_all(buf)
}
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
self.0.write_fmt(fmt)
}
}
impl WasiFile for Stderr {
fn last_accessed(&self) -> u64 {
0
}
fn last_modified(&self) -> u64 {
0
}
fn created_time(&self) -> u64 {
0
}
fn size(&self) -> u64 {
0
}
}
#[derive(Debug)]
pub struct Stdin(pub std::io::Stdin);
impl Read for Stdin {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
self.0.read_to_string(buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.0.read_exact(buf)
}
}
impl Seek for Stdin {
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not seek stdin",
))
}
}
impl Write for Stdin {
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not write to stdin",
))
}
fn flush(&mut self) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not write to stdin",
))
}
fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not write to stdin",
))
}
fn write_fmt(&mut self, _fmt: ::std::fmt::Arguments) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not write to stdin",
))
}
}
impl WasiFile for Stdin {
fn last_accessed(&self) -> u64 {
0
}
fn last_modified(&self) -> u64 {
0
}
fn created_time(&self) -> u64 {
0
}
fn size(&self) -> u64 {
0
}
}
/*
TODO: Think about using this
trait WasiFdBacking: std::fmt::Debug {
fn get_stat(&self) -> &__wasi_filestat_t;
fn get_stat_mut(&mut self) -> &mut __wasi_filestat_t;
fn is_preopened(&self) -> bool;
fn get_name(&self) -> &str;
}
*/

View File

@@ -9,8 +9,8 @@ use self::types::*;
use crate::{
ptr::{Array, WasmPtr},
state::{
self, host_file_type_to_wasi_file_type, Fd, Inode, InodeVal, Kind, WasiFile, WasiState,
MAX_SYMLINKS,
self, host_file_type_to_wasi_file_type, Fd, HostFile, Inode, InodeVal, Kind, WasiFile,
WasiState, MAX_SYMLINKS,
},
ExitCode,
};
@@ -342,6 +342,7 @@ pub fn fd_allocate(
Kind::Dir { .. } | Kind::Root { .. } => return __WASI_EISDIR,
}
state.fs.inodes[inode].stat.st_size = new_size;
debug!("New file size: {}", new_size);
__WASI_ESUCCESS
}
@@ -420,6 +421,11 @@ pub fn fd_fdstat_get(
);
let mut state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_FILESTAT_GET) {
return __WASI_EACCES;
}
let stat = wasi_try!(state.fs.fdstat(fd));
let buf = wasi_try!(buf_ptr.deref(memory));
@@ -1559,9 +1565,10 @@ pub fn path_open(
.create(o_flags & __WASI_O_CREAT != 0)
.truncate(o_flags & __WASI_O_TRUNC != 0);
*handle = Some(Box::new(wasi_try!(open_options
.open(&path)
.map_err(|_| __WASI_EIO))));
*handle = Some(Box::new(HostFile::new(
wasi_try!(open_options.open(&path).map_err(|_| __WASI_EIO)),
path.to_path_buf(),
)));
}
Kind::Buffer { .. } => unimplemented!("wasi::path_open for Buffer type files"),
Kind::Dir { .. } | Kind::Root { .. } => {
@@ -1618,14 +1625,13 @@ pub fn path_open(
.write(true)
.create_new(true);
Some(
Box::new(wasi_try!(open_options.open(&new_file_host_path).map_err(
|e| {
debug!("Error opening file {}", e);
__WASI_EIO
}
))) as Box<dyn WasiFile>,
)
Some(Box::new(HostFile::new(
wasi_try!(open_options.open(&new_file_host_path).map_err(|e| {
debug!("Error opening file {}", e);
__WASI_EIO
})),
new_file_host_path.clone(),
)) as Box<dyn WasiFile>)
};
let new_inode = {
@@ -1812,6 +1818,7 @@ pub fn path_unlink_file(
let base_dir = wasi_try!(state.fs.fd_map.get(&fd).ok_or(__WASI_EBADF));
let path_str = wasi_try!(path.get_utf8_string(memory, path_len).ok_or(__WASI_EINVAL));
debug!("Requested file: {}", path_str);
let inode = wasi_try!(state.fs.get_inode_at_path(fd, path_str, false));
let (parent_inode, childs_name) =