Use typetag so that we can still use serde

This commit is contained in:
Mark McCaskey 2019-08-27 15:18:12 -07:00
parent 51faeed2cf
commit e88a08f973
6 changed files with 225 additions and 180 deletions

77
Cargo.lock generated
View File

@ -409,6 +409,15 @@ dependencies = [
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ctor"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "digest"
version = "0.8.1"
@ -467,6 +476,14 @@ dependencies = [
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "erased-serde"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "errno"
version = "0.2.4"
@ -556,6 +573,16 @@ dependencies = [
"wasi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ghost"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.2.11"
@ -630,6 +657,26 @@ dependencies = [
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "inventory"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ctor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"inventory-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "inventory-impl"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itertools"
version = "0.8.0"
@ -1345,6 +1392,28 @@ name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typetag"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "typetag-impl"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-segmentation"
version = "1.3.0"
@ -1660,6 +1729,7 @@ dependencies = [
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime-core 0.6.0",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1805,12 +1875,14 @@ dependencies = [
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
"checksum ctor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5b6b2f4752cc29efbfd03474c532ce8f916f2d44ec5bb8c21f93bc76e5365528"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum dynasm 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f36d49ab6f8ecc642d2c6ee10fda04ba68003ef0277300866745cdde160e6b40"
"checksum dynasmrt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c408a211e7f5762829f5e46bdff0c14bc3b1517a21a4bb781c716bf88b0c68"
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
"checksum enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7798e7da2d4cb0d6d6fc467e8d6b5bf247e9e989f786dde1732d79899c32bb10"
"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
"checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60"
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
@ -1822,6 +1894,7 @@ dependencies = [
"checksum generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4024f96ffa0ebaaf36aa589cd41f2fd69f3a5e6fd02c86e11e12cdf41d5b46a3"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6171a6cc63fbabbe27c2b5ee268e8b7fe5dc1eb0dd2dfad537c1dfed6f69117e"
"checksum ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum goblin 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e3fa261d919c1ae9d1e4533c4a2f99e10938603c4208d56c05bec7a872b661b0"
@ -1831,6 +1904,8 @@ dependencies = [
"checksum indexmap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4d6d89e0948bf10c08b9ecc8ac5b83f07f857ebe2c0cbe38de15b4e4f510356"
"checksum inkwell 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = "<none>"
"checksum inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = "<none>"
"checksum inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4cece20baea71d9f3435e7bbe9adf4765f091c5fe404975f844006964a71299"
"checksum inventory-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2869bf972e998977b1cb87e60df70341d48e48dca0823f534feb91ea44adaf9"
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
@ -1918,6 +1993,8 @@ dependencies = [
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebb2c484029d695fb68a06d80e1536c68d491b3e0cf874c66abed255e831cfe"
"checksum typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b63fd4799e4d0ec5cf0b055ebb8e2c3a657bbf76a84f6edc77ca60780e000204"
"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"

View File

@ -15,6 +15,7 @@ libc = "0.2.60"
log = "0.4.8"
rand = "0.7.0"
time = "0.1.42"
typetag = "0.1"
serde = { version = "1", features = ["derive"] }
# wasmer-runtime-abi = { path = "../runtime-abi" }
wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }

View File

@ -49,8 +49,8 @@ pub fn generate_import_object(
let state = Box::new(WasiState {
fs: WasiFs::new(&preopened_files, &mapped_dirs).unwrap(),
args,
envs,
args: args.clone(),
envs: envs.clone(),
});
(

View File

@ -14,7 +14,7 @@ use std::{
borrow::Borrow,
cell::Cell,
fs,
io::{self, Write},
io::Write,
path::{Path, PathBuf},
time::SystemTime,
};
@ -47,7 +47,6 @@ pub struct InodeVal {
#[derive(Debug, Serialize, Deserialize)]
pub enum Kind {
File {
#[serde(skip)]
/// the open file, if it's open
handle: Option<Box<dyn WasiFile>>,
/// The path on the host system where the file is located
@ -107,7 +106,7 @@ impl Fd {
pub const CREATE: u16 = 16;
}
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
/// Warning, modifying these fields directly may cause invariants to break and
/// should be considered unsafe. These fields may be made private in a future release
pub struct WasiFs {
@ -142,9 +141,9 @@ impl WasiFs {
inode_counter: Cell::new(1024),
orphan_fds: HashMap::new(),
stdin: Box::new(Stdin(io::stdin())),
stdout: Box::new(Stdout(io::stdout())),
stderr: Box::new(Stderr(io::stderr())),
stdin: Box::new(Stdin),
stdout: Box::new(Stdout),
stderr: Box::new(Stderr),
};
// create virtual root
let root_inode = {
@ -932,44 +931,9 @@ impl WasiFs {
..__wasi_filestat_t::default()
})
}
pub(crate) fn unfreeze(bytes: &[u8]) -> Option<(WasiFs, &[u8])> {
unimplemented!()
Some((Self {
preopen_fds,
name_map,
inodes,
fd_map,
next_fd,
inode_counter,
orphan_fds,
stdout,
stderr,
stdin
}, unimplemented!()))
}
pub(crate) fn freeze(&self) -> Option<Vec<u8>> {
let mut out = vec![];
// store pointer to stdout, stderr, and stdin here I guess
// hmmm
out.append(&mut bincode::serialize(&self.preopen_fds).ok()?);
out.append(&mut bincode::serialize(&self.name_map).ok()?);
out.append(&mut bincode::serialize(&self.inodes).ok()?);
out.append(&mut bincode::serialize(&self.fd_map).ok()?);
out.append(&mut bincode::serialize(&self.next_fd).ok()?);
out.append(&mut bincode::serialize(&self.inode_counter).ok()?);
out.append(&mut bincode::serialize(&self.orphan_fds).ok()?);
out.append(&mut self.stdout.to_bytes()?);
out.append(&mut self.stderr.to_bytes()?);
out.append(&mut self.stdin.to_bytes()?);
Some(out)
}
}
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct WasiState {
pub fs: WasiFs,
pub args: Vec<Vec<u8>>,
@ -979,32 +943,12 @@ pub struct WasiState {
impl WasiState {
/// Turn the WasiState into bytes
pub fn freeze(&self) -> Option<Vec<u8>> {
let wasi_fs = self.wasi_fs.freeze()?;
let args = bincode::serialize(&self.args).ok()?;
let envs = bincode::serialize(&self.envs).ok()?;
Some(
wasi_fs
.into_iter()
.chain(args.into_iter())
.chain(envs.into_iter())
.collect(),
)
bincode::serialize(self).ok()
}
/// Get a WasiState from bytes
pub fn unfreeze<F>(bytes: &[u8], deserialize_fns: Vec<Box<F>>) -> Option<Self>
where
F: Fn(&[u8]) -> Option<Box<dyn WasiFile>>,
{
let (wasi_fs, remaining_bytes) = WasiFs::unfreeze(bytes)?;
let (args, envs): (Vec<Vec<u8>>, Vec<Vec<u8>>) =
bincode::deserialize(remaining_bytes).ok()?;
Some(Self {
fs: wasi_fs,
args,
envs,
})
pub fn unfreeze(bytes: &[u8]) -> Option<Self> {
bincode::deserialize(bytes).ok()
}
}

View File

@ -1,10 +1,11 @@
/// types for use in the WASI filesystem
use crate::syscalls::types::*;
use serde::{Deserialize, Serialize};
#[cfg(unix)]
use std::convert::TryInto;
use std::{
fs,
io::{self, Read, Seek, SeekFrom, Write},
io::{self, Read, Seek, Write},
path::PathBuf,
time::SystemTime,
};
@ -117,6 +118,7 @@ impl WasiFsError {
}
/// This trait relies on your file closing when it goes out of scope via `Drop`
#[typetag::serde(tag = "type")]
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;
@ -178,29 +180,6 @@ pub trait WasiFile: std::fmt::Debug + Write + Read + Seek {
fn get_raw_fd(&self) -> Option<i32> {
None
}
/// Try to turn the file into bytes
fn to_bytes(&self) -> Option<Vec<u8>>;
}
/// Tries to read a WASI file out of bytes
/// with default parsers for stdin/stdout/stderr and `HostFile`
pub fn wasi_file_from_bytes(bytes: &[u8]) -> Option<Box<dyn WasiFile>> {
Some(if b"stdout"[..] == bytes[.."stdout".len()] {
Box::new(Stdout(std::io::stdout()))
} else if b"stderr"[..] == bytes[.."stderr".len()] {
Box::new(Stderr(std::io::stderr()))
} else if b"stdin"[..] == bytes[.."stdin".len()] {
Box::new(Stdin(std::io::stdin()))
} else if b"host_file"[..] == bytes[.."host_file".len()] {
unimplemented!();
} else {
return None;
})
}
pub(crate) fn serialize_file<E: Default>(file: Box<dyn WasiFile>) -> Result<Vec<u8>, E> {
file.to_bytes().ok_or_else(|| Default::default())
}
#[derive(Debug, Clone)]
@ -362,18 +341,90 @@ pub(crate) fn poll(
pub trait WasiPath {}
/// A thin wrapper around `std::fs::File`
#[derive(Debug)]
#[derive(Debug, Serialize)]
pub struct HostFile {
#[serde(skip_serializing)]
pub inner: fs::File,
pub host_path: PathBuf,
flags: u16,
}
struct HostFileVisitor;
impl<'de> serde::de::Visitor<'de> for HostFileVisitor {
type Value = HostFile;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a HostFile struct")
}
/*fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> {
let host_path = unimplemented!();
let flags = unimplemented!();
Ok(HostFile {
inner,
host_path,
flags,
})
}*/
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
where
V: serde::de::SeqAccess<'de>,
{
let host_path = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
let flags = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
let inner = std::fs::OpenOptions::new()
.read(flags & HostFile::READ != 0)
.write(flags & HostFile::WRITE != 0)
.append(flags & HostFile::APPEND != 0)
.open(&host_path)
.map_err(|_| serde::de::Error::custom("Could not open file on this system"))?;
Ok(HostFile {
inner,
host_path,
flags,
})
}
}
impl<'de> Deserialize<'de> for HostFile {
fn deserialize<D>(deserializer: D) -> Result<HostFile, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_i32(HostFileVisitor)
}
}
// manually implement Deserialize here such that it uses actual data to open a file;
// I guess we need to add r/w flags and stuff here too..
impl HostFile {
const READ: u16 = 1;
const WRITE: u16 = 2;
const APPEND: u16 = 4;
/// creates a new host file from a `std::fs::File` and a path
pub fn new(file: fs::File, host_path: PathBuf) -> Self {
pub fn new(file: fs::File, host_path: PathBuf, read: bool, write: bool, append: bool) -> Self {
let mut flags = 0;
if read {
flags |= Self::READ;
}
if write {
flags |= Self::WRITE;
}
if append {
flags |= Self::APPEND;
}
Self {
inner: file,
host_path,
flags,
}
}
@ -416,6 +467,7 @@ impl Write for HostFile {
}
}
#[typetag::serde]
impl WasiFile for HostFile {
fn last_accessed(&self) -> u64 {
self.metadata()
@ -508,23 +560,6 @@ impl WasiFile for HostFile {
"HostFile::get_raw_fd in WasiFile is not implemented for non-Unix-like targets yet"
);
}
fn to_bytes(&self) -> Option<Vec<u8>> {
let mut out = vec![];
for c in "host_file".chars() {
out.push(c as u8);
}
let cursor = self.inner.seek(SeekFrom::Current(0)).ok()?;
// store r/w/append info here? or is this handeled somewhere else?
for b in cursor.to_le_bytes().into_iter() {
out.push(*b);
}
for b in self.host_path.to_string_lossy().bytes() {
out.push(b);
}
Some(out)
}
}
impl From<io::Error> for WasiFsError {
@ -554,57 +589,55 @@ impl From<io::Error> for WasiFsError {
}
}
#[derive(Debug)]
pub struct Stdout(pub std::io::Stdout);
#[derive(Debug, Serialize, Deserialize)]
pub struct Stdout;
impl Read for Stdout {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
Err(io::Error::new(
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,
Err(io::Error::new(
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,
Err(io::Error::new(
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,
Err(io::Error::new(
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",
))
Err(io::Error::new(io::ErrorKind::Other, "can not seek stdout"))
}
}
impl Write for Stdout {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
io::stdout().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
io::stdout().flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.0.write_all(buf)
io::stdout().write_all(buf)
}
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
self.0.write_fmt(fmt)
io::stdout().write_fmt(fmt)
}
}
#[typetag::serde]
impl WasiFile for Stdout {
fn last_accessed(&self) -> u64 {
0
@ -622,7 +655,7 @@ impl WasiFile for Stdout {
#[cfg(unix)]
fn get_raw_fd(&self) -> Option<i32> {
use std::os::unix::io::AsRawFd;
Some(self.0.as_raw_fd())
Some(io::stdout().as_raw_fd())
}
#[cfg(not(unix))]
@ -631,63 +664,57 @@ impl WasiFile for Stdout {
"Stdout::get_raw_fd in WasiFile is not implemented for non-Unix-like targets yet"
);
}
fn to_bytes(&self) -> Option<Vec<u8>> {
Some("stdout".chars().map(|c| c as u8).collect())
}
}
#[derive(Debug)]
pub struct Stderr(pub std::io::Stderr);
#[derive(Debug, Serialize, Deserialize)]
pub struct Stderr;
impl Read for Stderr {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
Err(io::Error::new(
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,
Err(io::Error::new(
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,
Err(io::Error::new(
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,
Err(io::Error::new(
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",
))
Err(io::Error::new(io::ErrorKind::Other, "can not seek stderr"))
}
}
impl Write for Stderr {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
io::stderr().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
io::stderr().flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.0.write_all(buf)
io::stderr().write_all(buf)
}
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
self.0.write_fmt(fmt)
io::stderr().write_fmt(fmt)
}
}
#[typetag::serde]
impl WasiFile for Stderr {
fn last_accessed(&self) -> u64 {
0
@ -705,7 +732,7 @@ impl WasiFile for Stderr {
#[cfg(unix)]
fn get_raw_fd(&self) -> Option<i32> {
use std::os::unix::io::AsRawFd;
Some(self.0.as_raw_fd())
Some(io::stderr().as_raw_fd())
}
#[cfg(not(unix))]
@ -714,63 +741,57 @@ impl WasiFile for Stderr {
"Stderr::get_raw_fd in WasiFile is not implemented for non-Unix-like targets yet"
);
}
fn to_bytes(&self) -> Option<Vec<u8>> {
Some("stderr".chars().map(|c| c as u8).collect())
}
}
#[derive(Debug)]
pub struct Stdin(pub std::io::Stdin);
#[derive(Debug, Serialize, Deserialize)]
pub struct Stdin;
impl Read for Stdin {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
io::stdin().read(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
io::stdin().read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
self.0.read_to_string(buf)
io::stdin().read_to_string(buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.0.read_exact(buf)
io::stdin().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",
))
Err(io::Error::new(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,
Err(io::Error::new(
io::ErrorKind::Other,
"can not write to stdin",
))
}
fn flush(&mut self) -> io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
Err(io::Error::new(
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,
Err(io::Error::new(
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,
Err(io::Error::new(
io::ErrorKind::Other,
"can not write to stdin",
))
}
}
#[typetag::serde]
impl WasiFile for Stdin {
fn last_accessed(&self) -> u64 {
0
@ -788,7 +809,7 @@ impl WasiFile for Stdin {
#[cfg(unix)]
fn bytes_available(&self) -> Result<usize, WasiFsError> {
use std::os::unix::io::AsRawFd;
let host_fd = self.0.as_raw_fd();
let host_fd = io::stdin().as_raw_fd();
let mut bytes_found = 0 as libc::c_int;
let result = unsafe { libc::ioctl(host_fd, libc::FIONREAD, &mut bytes_found) };
@ -812,7 +833,7 @@ impl WasiFile for Stdin {
#[cfg(unix)]
fn get_raw_fd(&self) -> Option<i32> {
use std::os::unix::io::AsRawFd;
Some(self.0.as_raw_fd())
Some(io::stdin().as_raw_fd())
}
#[cfg(not(unix))]
@ -821,10 +842,6 @@ impl WasiFile for Stdin {
"Stdin::get_raw_fd in WasiFile is not implemented for non-Unix-like targets yet"
);
}
fn to_bytes(&self) -> Option<Vec<u8>> {
Some("stdin".chars().map(|c| c as u8).collect())
}
}
/*

View File

@ -1704,6 +1704,9 @@ pub fn path_open(
*handle = Some(Box::new(HostFile::new(
wasi_try!(open_options.open(&path).map_err(|_| __WASI_EIO)),
path.to_path_buf(),
true,
adjusted_rights & __WASI_RIGHT_FD_WRITE != 0,
false,
)));
}
Kind::Buffer { .. } => unimplemented!("wasi::path_open for Buffer type files"),
@ -1768,6 +1771,9 @@ pub fn path_open(
__WASI_EIO
})),
new_file_host_path.clone(),
true,
true,
true,
)) as Box<dyn WasiFile>)
};