From e88a08f973ba3f83382445b90d8d68ebc854d511 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 27 Aug 2019 15:18:12 -0700 Subject: [PATCH] Use typetag so that we can still use serde --- Cargo.lock | 77 +++++++++++ lib/wasi/Cargo.toml | 1 + lib/wasi/src/lib.rs | 4 +- lib/wasi/src/state/mod.rs | 74 ++--------- lib/wasi/src/state/types.rs | 243 +++++++++++++++++++---------------- lib/wasi/src/syscalls/mod.rs | 6 + 6 files changed, 225 insertions(+), 180 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e8bf1ca9f..83301a509 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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)" = "" "checksum inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = "" +"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" diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 0bc79362e..da72bb3af 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -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" } diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index f1a19d679..c5a808874 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -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(), }); ( diff --git a/lib/wasi/src/state/mod.rs b/lib/wasi/src/state/mod.rs index fccdd9480..a4154733d 100644 --- a/lib/wasi/src/state/mod.rs +++ b/lib/wasi/src/state/mod.rs @@ -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>, /// 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> { - 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>, @@ -979,32 +943,12 @@ pub struct WasiState { impl WasiState { /// Turn the WasiState into bytes pub fn freeze(&self) -> Option> { - 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(bytes: &[u8], deserialize_fns: Vec>) -> Option - where - F: Fn(&[u8]) -> Option>, - { - let (wasi_fs, remaining_bytes) = WasiFs::unfreeze(bytes)?; - let (args, envs): (Vec>, Vec>) = - bincode::deserialize(remaining_bytes).ok()?; - Some(Self { - fs: wasi_fs, - args, - envs, - }) + pub fn unfreeze(bytes: &[u8]) -> Option { + bincode::deserialize(bytes).ok() } } diff --git a/lib/wasi/src/state/types.rs b/lib/wasi/src/state/types.rs index 1b3c73c5a..1032e2279 100644 --- a/lib/wasi/src/state/types.rs +++ b/lib/wasi/src/state/types.rs @@ -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 { None } - - /// Try to turn the file into bytes - fn to_bytes(&self) -> Option>; -} - -/// 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> { - 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(file: Box) -> Result, 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(self, v: &[u8]) -> Result { + let host_path = unimplemented!(); + let flags = unimplemented!(); + Ok(HostFile { + inner, + host_path, + flags, + }) + }*/ + + fn visit_seq(self, mut seq: V) -> Result + 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(deserializer: D) -> Result + 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> { - 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 for WasiFsError { @@ -554,57 +589,55 @@ impl From 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 { - 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) -> io::Result { - 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 { - 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 { - 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 { - 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 { 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> { - 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 { - 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) -> io::Result { - 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 { - 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 { - 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 { - 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 { 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> { - 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 { - self.0.read(buf) + io::stdin().read(buf) } fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { - self.0.read_to_end(buf) + io::stdin().read_to_end(buf) } fn read_to_string(&mut self, buf: &mut String) -> io::Result { - 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 { - 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 { - 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 { 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 { 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> { - Some("stdin".chars().map(|c| c as u8).collect()) - } } /* diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index cc568997d..b619c530a 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -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) };