mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-24 18:02:13 +00:00
Use typetag so that we can still use serde
This commit is contained in:
parent
51faeed2cf
commit
e88a08f973
77
Cargo.lock
generated
77
Cargo.lock
generated
@ -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"
|
||||
|
@ -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" }
|
||||
|
@ -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(),
|
||||
});
|
||||
|
||||
(
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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>)
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user