diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7b7179327f..2e2b31abee 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,7 +58,7 @@ jobs: submodules: true - uses: ./.github/actions/install-rust with: - toolchain: nightly-2021-04-11 + toolchain: nightly-2021-07-12 # Build C API documentation - run: sudo apt-get update -y && sudo apt-get install -y libclang1-9 libclang-cpp9 @@ -175,7 +175,7 @@ jobs: # flags to rustc. - uses: ./.github/actions/install-rust with: - toolchain: nightly-2021-04-11 + toolchain: nightly-2021-07-12 - run: cargo install cargo-fuzz --vers "^0.8" - run: cargo fetch working-directory: ./fuzz diff --git a/Cargo.lock b/Cargo.lock index 900147e716..3a20b49686 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,6 +86,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "ambient-authority" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0612772f30c7c0f946a4248bcff6e71a2512c725f30f8c1e2ad8e796aa54d14" + [[package]] name = "ansi_term" version = "0.11.0" @@ -281,27 +287,28 @@ checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" [[package]] name = "cap-fs-ext" -version = "0.13.10" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff3a1e32332db9ad29d6da34693ce9a7ac26a9edf96abb5c1788d193410031ab" +checksum = "0a43efcdd826967e3290b6a7ef739c1fc1d061fcba73f487716f4e579fc49160" dependencies = [ "cap-primitives", "cap-std", + "io-lifetimes", "rustc_version", - "unsafe-io", "winapi", ] [[package]] name = "cap-primitives" -version = "0.13.10" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d253b74de50b097594462618e7dd17b93b3e3bef19f32d2e512996f9095661f" +checksum = "06ebdaf00e31635731cb79a58d495f4e9566cfcf7f992774913209edc4a8400a" dependencies = [ + "ambient-authority", "errno", "fs-set-times", + "io-lifetimes", "ipnet", - "libc", "maybe-owned", "once_cell", "posish", @@ -314,20 +321,23 @@ dependencies = [ [[package]] name = "cap-rand" -version = "0.13.10" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458e98ed00e4276d0ac60da888d80957a177dfa7efa8dbb3be59f1e2b0e02ae5" +checksum = "053048ae91b2a2243496e6cb1fc7fed999bd0996335899037b157ac1b2e5941b" dependencies = [ + "ambient-authority", "rand 0.8.3", ] [[package]] name = "cap-std" -version = "0.13.10" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7019d48ea53c5f378e0fdab0fe5f627fc00e76d65e75dffd6fb1cbc0c9b382ee" +checksum = "dc0db75321794c647dc4a4288570db267263b2645c72a357f679ed537dc7a364" dependencies = [ "cap-primitives", + "io-lifetimes", + "ipnet", "posish", "rustc_version", "unsafe-io", @@ -335,9 +345,9 @@ dependencies = [ [[package]] name = "cap-tempfile" -version = "0.13.10" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d1090f8597e39d10588664760f081edb5748562396a490a75615eafc99d1c8f" +checksum = "d9d897dd9bcb53f69b3613f3d317b4492a7f85c3eef950a59126b9f4f83c7d0e" dependencies = [ "cap-std", "rand 0.8.3", @@ -346,9 +356,9 @@ dependencies = [ [[package]] name = "cap-time-ext" -version = "0.13.10" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90585adeada7f804e6dcf71b8ff74217ad8742188fc870b9da5deab4722baa04" +checksum = "f093889016cd7cea400030dd352557c61fd974b99c504f3a5cdc409f9d18b18b" dependencies = [ "cap-primitives", "once_cell", @@ -378,9 +388,9 @@ dependencies = [ [[package]] name = "cast" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57cdfa5d50aad6cb4d44dcab6101a7f79925bd59d82ca42f38a9856a28865374" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" dependencies = [ "rustc_version", ] @@ -899,6 +909,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "cstr" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "csv" version = "1.1.6" @@ -1249,12 +1269,12 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fs-set-times" -version = "0.3.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f1ca01f517bba5770c067dc6c466d290b962e08214c8f2598db98d66087e55" +checksum = "56af20dae05f9fae64574ead745ced5f08ae7dc6f42b9facd93a43d4b7adf982" dependencies = [ + "io-lifetimes", "posish", - "unsafe-io", "winapi", ] @@ -1452,6 +1472,17 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "io-lifetimes" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d009010297118b0a443fef912b92e3482e6e6f46ab31e5d60f68b39a553ca9" +dependencies = [ + "libc", + "rustc_version", + "winapi", +] + [[package]] name = "ipnet" version = "2.3.0" @@ -1555,9 +1586,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" +checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "libfuzzer-sys" @@ -1610,6 +1641,12 @@ dependencies = [ "wat", ] +[[package]] +name = "linux-raw-sys" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a0e0375b6446268ee5299c8e92f90030c719b8bb6fcc303a704080da790654" + [[package]] name = "lock_api" version = "0.4.4" @@ -2087,15 +2124,6 @@ dependencies = [ "regex", ] -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - [[package]] name = "pin-project-lite" version = "0.2.6" @@ -2164,16 +2192,20 @@ dependencies = [ [[package]] name = "posish" -version = "0.6.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1601f90b2342aaf3aadb891b71f584155d176b0e891bea92eeb11995e0ab25" +checksum = "2de73ab12ea55715a4217377e614fc2900f84e9366d1f5c0601fe2aa5e25fe86" dependencies = [ "bitflags", - "cfg-if 1.0.0", + "cc", + "cstr", "errno", + "io-lifetimes", "itoa", "libc", - "unsafe-io", + "linux-raw-sys", + "once_cell", + "rustc_version", ] [[package]] @@ -2575,9 +2607,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_version" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ "semver", ] @@ -2637,21 +2669,9 @@ dependencies = [ [[package]] name = "semver" -version = "0.11.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] +checksum = "5f3aac57ee7f3272d8395c6e4f502f434f0e289fcd62876f70daa008c20dcabe" [[package]] name = "serde" @@ -2882,17 +2902,17 @@ dependencies = [ [[package]] name = "system-interface" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a6aa8a77b9b8b533ec5a178ce0ea749c3a6cc6a79d0d38c89cd257dc4e34eb" +checksum = "7adf9f33595b165d9d2897c548750a1141fc531a2492f7d365b71190c063e836" dependencies = [ "atty", "bitflags", "cap-fs-ext", "cap-std", + "io-lifetimes", "posish", "rustc_version", - "unsafe-io", "winapi", "winx", ] @@ -3147,12 +3167,6 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - [[package]] name = "unicode-segmentation" version = "1.7.1" @@ -3192,10 +3206,11 @@ dependencies = [ [[package]] name = "unsafe-io" -version = "0.6.9" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f372ce89b46cb10aace91021ff03f26cf97594f7515c0a8c1c2839c13814665d" +checksum = "f56d1d7067d6e88dfdede7f668ea51800785fc8fcaf82d8fecdeaa678491e629" dependencies = [ + "io-lifetimes", "rustc_version", "winapi", ] @@ -3296,12 +3311,12 @@ dependencies = [ "cap-std", "cap-time-ext", "fs-set-times", + "io-lifetimes", "lazy_static", - "libc", + "posish", "system-interface", "tempfile", "tracing", - "unsafe-io", "wasi-common", "winapi", ] @@ -3314,7 +3329,8 @@ dependencies = [ "bitflags", "cap-rand", "cap-std", - "libc", + "io-lifetimes", + "posish", "thiserror", "tracing", "wiggle", @@ -3361,14 +3377,13 @@ dependencies = [ "cap-tempfile", "cap-time-ext", "fs-set-times", + "io-lifetimes", "lazy_static", - "libc", "posish", "system-interface", "tempfile", "tokio", "tracing", - "unsafe-io", "wasi-cap-std-sync", "wasi-common", "wiggle", @@ -3985,11 +4000,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winx" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdb79e12a5ac98f09e863b99c38c72f942a41f643ae0bb05d4d6d2633481341" +checksum = "cc8ca6af61cfeed1e071b19f44cf4a7683addd863f28fef69cdf251bc034050e" dependencies = [ "bitflags", + "io-lifetimes", "winapi", ] diff --git a/crates/bench-api/Cargo.toml b/crates/bench-api/Cargo.toml index 701fcc7676..9cebe20b57 100644 --- a/crates/bench-api/Cargo.toml +++ b/crates/bench-api/Cargo.toml @@ -22,7 +22,7 @@ wasmtime-wasi = { path = "../wasi" } wasmtime-wasi-crypto = { path = "../wasi-crypto", optional = true } wasmtime-wasi-nn = { path = "../wasi-nn", optional = true } wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync" } -cap-std = "0.13" +cap-std = "0.16.0" [dev-dependencies] wat = "1.0" diff --git a/crates/bench-api/src/lib.rs b/crates/bench-api/src/lib.rs index 8835391b07..4a8942011b 100644 --- a/crates/bench-api/src/lib.rs +++ b/crates/bench-api/src/lib.rs @@ -244,13 +244,14 @@ pub extern "C" fn wasm_bench_create( ) -> ExitCode { let result = (|| -> Result<_> { let working_dir = config.working_dir()?; - let working_dir = unsafe { cap_std::fs::Dir::open_ambient_dir(&working_dir) } - .with_context(|| { - format!( - "failed to preopen the working directory: {}", - working_dir.display(), - ) - })?; + let working_dir = + cap_std::fs::Dir::open_ambient_dir(&working_dir, cap_std::ambient_authority()) + .with_context(|| { + format!( + "failed to preopen the working directory: {}", + working_dir.display(), + ) + })?; let stdout_path = config.stdout_path()?; let stderr_path = config.stderr_path()?; @@ -271,20 +272,20 @@ pub extern "C" fn wasm_bench_create( let stdout = std::fs::File::create(&stdout_path) .with_context(|| format!("failed to create {}", stdout_path.display()))?; - let stdout = unsafe { cap_std::fs::File::from_std(stdout) }; + let stdout = cap_std::fs::File::from_std(stdout, cap_std::ambient_authority()); let stdout = wasi_cap_std_sync::file::File::from_cap_std(stdout); cx = cx.stdout(Box::new(stdout)); let stderr = std::fs::File::create(&stderr_path) .with_context(|| format!("failed to create {}", stderr_path.display()))?; - let stderr = unsafe { cap_std::fs::File::from_std(stderr) }; + let stderr = cap_std::fs::File::from_std(stderr, cap_std::ambient_authority()); let stderr = wasi_cap_std_sync::file::File::from_cap_std(stderr); cx = cx.stderr(Box::new(stderr)); if let Some(stdin_path) = &stdin_path { let stdin = std::fs::File::open(stdin_path) .with_context(|| format!("failed to open {}", stdin_path.display()))?; - let stdin = unsafe { cap_std::fs::File::from_std(stdin) }; + let stdin = cap_std::fs::File::from_std(stdin, cap_std::ambient_authority()); let stdin = wasi_cap_std_sync::file::File::from_cap_std(stdin); cx = cx.stdin(Box::new(stdin)); } diff --git a/crates/c-api/Cargo.toml b/crates/c-api/Cargo.toml index be28ee1731..4683d0a280 100644 --- a/crates/c-api/Cargo.toml +++ b/crates/c-api/Cargo.toml @@ -30,7 +30,7 @@ wat = { version = "1.0.36", optional = true } wasi-common = { path = "../wasi-common", optional = true } wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync", optional = true } wasmtime-wasi = { path = "../wasi", optional = true } -cap-std = { version = "0.13", optional = true } +cap-std = { version = "0.16.0", optional = true } [features] default = ['jitdump', 'wat', 'wasi', 'cache'] diff --git a/crates/c-api/src/wasi.rs b/crates/c-api/src/wasi.rs index 411d29c1c4..70980ec7c2 100644 --- a/crates/c-api/src/wasi.rs +++ b/crates/c-api/src/wasi.rs @@ -1,6 +1,7 @@ //! The WASI embedding API definitions for Wasmtime. use anyhow::Result; +use cap_std::ambient_authority; use std::ffi::CStr; use std::fs::File; use std::os::raw::{c_char, c_int}; @@ -69,21 +70,21 @@ impl wasi_config_t { if self.inherit_stdin { builder = builder.inherit_stdin(); } else if let Some(file) = self.stdin { - let file = unsafe { cap_std::fs::File::from_std(file) }; + let file = cap_std::fs::File::from_std(file, ambient_authority()); let file = wasi_cap_std_sync::file::File::from_cap_std(file); builder = builder.stdin(Box::new(file)); } if self.inherit_stdout { builder = builder.inherit_stdout(); } else if let Some(file) = self.stdout { - let file = unsafe { cap_std::fs::File::from_std(file) }; + let file = cap_std::fs::File::from_std(file, ambient_authority()); let file = wasi_cap_std_sync::file::File::from_cap_std(file); builder = builder.stdout(Box::new(file)); } if self.inherit_stderr { builder = builder.inherit_stderr(); } else if let Some(file) = self.stderr { - let file = unsafe { cap_std::fs::File::from_std(file) }; + let file = cap_std::fs::File::from_std(file, ambient_authority()); let file = wasi_cap_std_sync::file::File::from_cap_std(file); builder = builder.stderr(Box::new(file)); } @@ -227,7 +228,7 @@ pub unsafe extern "C" fn wasi_config_preopen_dir( }; let dir = match cstr_to_path(path) { - Some(p) => match Dir::open_ambient_dir(p) { + Some(p) => match Dir::open_ambient_dir(p, ambient_authority()) { Ok(d) => d, Err(_) => return false, }, diff --git a/crates/test-programs/Cargo.toml b/crates/test-programs/Cargo.toml index 293d6555f5..9e9fed0ac2 100644 --- a/crates/test-programs/Cargo.toml +++ b/crates/test-programs/Cargo.toml @@ -21,7 +21,7 @@ tempfile = "3.1.0" os_pipe = "0.9" anyhow = "1.0.19" wat = "1.0.37" -cap-std = "0.13" +cap-std = "0.16.0" tokio = { version = "1.8.0", features = ["rt-multi-thread"] } [features] diff --git a/crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs b/crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs index bea5406b47..80569ee7a5 100644 --- a/crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs +++ b/crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs @@ -46,7 +46,8 @@ fn run( if let Some(workspace) = workspace { println!("preopen: {:?}", workspace); - let preopen_dir = unsafe { cap_std::fs::Dir::open_ambient_dir(workspace) }?; + let preopen_dir = + cap_std::fs::Dir::open_ambient_dir(workspace, cap_std::ambient_authority())?; builder = builder.preopened_dir(preopen_dir, ".")?; } for (var, val) in super::test_suite_environment() { diff --git a/crates/test-programs/tests/wasm_tests/runtime/tokio.rs b/crates/test-programs/tests/wasm_tests/runtime/tokio.rs index d8870af511..3eb23e8a3f 100644 --- a/crates/test-programs/tests/wasm_tests/runtime/tokio.rs +++ b/crates/test-programs/tests/wasm_tests/runtime/tokio.rs @@ -51,7 +51,8 @@ fn run( if let Some(workspace) = workspace { println!("preopen: {:?}", workspace); - let preopen_dir = unsafe { cap_std::fs::Dir::open_ambient_dir(workspace) }?; + let preopen_dir = + cap_std::fs::Dir::open_ambient_dir(workspace, cap_std::ambient_authority())?; builder = builder.preopened_dir(preopen_dir, ".")?; } diff --git a/crates/test-programs/wasi-tests/src/bin/interesting_paths.rs b/crates/test-programs/wasi-tests/src/bin/interesting_paths.rs index 7e112167b8..34b1f83997 100644 --- a/crates/test-programs/wasi-tests/src/bin/interesting_paths.rs +++ b/crates/test-programs/wasi-tests/src/bin/interesting_paths.rs @@ -43,6 +43,7 @@ unsafe fn test_interesting_paths(dir_fd: wasi::Fd, arg: &str) { wasi::path_open(dir_fd, 0, "dir/nested/file\0", 0, 0, 0, 0) .expect_err("opening a file with a trailing NUL") .raw_error(), + wasi::ERRNO_INVAL, wasi::ERRNO_ILSEQ ); diff --git a/crates/wasi-common/Cargo.toml b/crates/wasi-common/Cargo.toml index e9a2262c70..76d5fb9d28 100644 --- a/crates/wasi-common/Cargo.toml +++ b/crates/wasi-common/Cargo.toml @@ -22,12 +22,13 @@ anyhow = "1.0" thiserror = "1.0" wiggle = { path = "../wiggle", default-features = false, version = "0.28.0" } tracing = "0.1.19" -cap-std = "0.13" -cap-rand = "0.13" +cap-std = "0.16.0" +cap-rand = "0.16.0" bitflags = "1.2" +io-lifetimes = "0.2.0" [target.'cfg(unix)'.dependencies] -libc = "0.2" +posish = "0.16.0" [target.'cfg(windows)'.dependencies] winapi = "0.3" diff --git a/crates/wasi-common/cap-std-sync/Cargo.toml b/crates/wasi-common/cap-std-sync/Cargo.toml index c2228015c1..055e687759 100644 --- a/crates/wasi-common/cap-std-sync/Cargo.toml +++ b/crates/wasi-common/cap-std-sync/Cargo.toml @@ -15,18 +15,18 @@ include = ["src/**/*", "README.md", "LICENSE" ] wasi-common = { path = "../", version = "0.28.0" } async-trait = "0.1" anyhow = "1.0" -cap-std = "0.13.10" -cap-fs-ext = "0.13.10" -cap-time-ext = "0.13.10" -cap-rand = "0.13.10" -fs-set-times = "0.3.1" -unsafe-io = "0.6.5" -system-interface = { version = "0.6.4", features = ["cap_std_impls"] } +cap-std = "0.16.0" +cap-fs-ext = "0.16.0" +cap-time-ext = "0.16.0" +cap-rand = "0.16.0" +fs-set-times = "0.6.0" +system-interface = { version = "0.8.0", features = ["cap_std_impls"] } tracing = "0.1.19" bitflags = "1.2" +io-lifetimes = "0.2.0" [target.'cfg(unix)'.dependencies] -libc = "0.2" +posish = "0.16.0" [target.'cfg(windows)'.dependencies] winapi = "0.3" diff --git a/crates/wasi-common/cap-std-sync/src/clocks.rs b/crates/wasi-common/cap-std-sync/src/clocks.rs index 3f17ae1e48..19e357435a 100644 --- a/crates/wasi-common/cap-std-sync/src/clocks.rs +++ b/crates/wasi-common/cap-std-sync/src/clocks.rs @@ -1,12 +1,13 @@ use cap_std::time::{Duration, Instant, SystemTime}; +use cap_std::{ambient_authority, AmbientAuthority}; use cap_time_ext::{MonotonicClockExt, SystemClockExt}; use wasi_common::clocks::{WasiClocks, WasiMonotonicClock, WasiSystemClock}; pub struct SystemClock(cap_std::time::SystemClock); impl SystemClock { - pub unsafe fn new() -> Self { - SystemClock(cap_std::time::SystemClock::new()) + pub fn new(ambient_authority: AmbientAuthority) -> Self { + SystemClock(cap_std::time::SystemClock::new(ambient_authority)) } } impl WasiSystemClock for SystemClock { @@ -20,8 +21,8 @@ impl WasiSystemClock for SystemClock { pub struct MonotonicClock(cap_std::time::MonotonicClock); impl MonotonicClock { - pub unsafe fn new() -> Self { - MonotonicClock(cap_std::time::MonotonicClock::new()) + pub fn new(ambient_authority: AmbientAuthority) -> Self { + MonotonicClock(cap_std::time::MonotonicClock::new(ambient_authority)) } } impl WasiMonotonicClock for MonotonicClock { @@ -34,8 +35,8 @@ impl WasiMonotonicClock for MonotonicClock { } pub fn clocks_ctx() -> WasiClocks { - let system = Box::new(unsafe { SystemClock::new() }); - let monotonic = unsafe { cap_std::time::MonotonicClock::new() }; + let system = Box::new(SystemClock::new(ambient_authority())); + let monotonic = cap_std::time::MonotonicClock::new(ambient_authority()); let creation_time = monotonic.now(); let monotonic = Box::new(MonotonicClock(monotonic)); WasiClocks { diff --git a/crates/wasi-common/cap-std-sync/src/dir.rs b/crates/wasi-common/cap-std-sync/src/dir.rs index d4e9a6db6e..8e5bf481d6 100644 --- a/crates/wasi-common/cap-std-sync/src/dir.rs +++ b/crates/wasi-common/cap-std-sync/src/dir.rs @@ -74,7 +74,8 @@ impl Dir { let mut f = self.0.open_with(Path::new(path), &opts)?; // NONBLOCK does not have an OpenOption either, but we can patch that on with set_fd_flags: if fdflags.contains(wasi_common::file::FdFlags::NONBLOCK) { - f.set_fd_flags(system_interface::fs::FdFlags::NONBLOCK)?; + let set_fd_flags = f.new_set_fd_flags(system_interface::fs::FdFlags::NONBLOCK)?; + f.set_fd_flags(set_fd_flags)?; } Ok(File::from_cap_std(f)) } @@ -311,13 +312,14 @@ fn convert_systimespec(t: Option) -> Option Result { let meta = self.0.metadata()?; @@ -151,20 +153,20 @@ pub fn filetype_from(ft: &cap_std::fs::FileType) -> FileType { } #[cfg(windows)] -use std::os::windows::io::{AsRawHandle, RawHandle}; +use io_lifetimes::{AsHandle, BorrowedHandle}; #[cfg(windows)] -impl AsRawHandle for File { - fn as_raw_handle(&self) -> RawHandle { - self.0.as_raw_handle() +impl AsHandle for File { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.0.as_handle() } } #[cfg(unix)] -use std::os::unix::io::{AsRawFd, RawFd}; +use io_lifetimes::{AsFd, BorrowedFd}; #[cfg(unix)] -impl AsRawFd for File { - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() +impl AsFd for File { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() } } pub fn convert_systimespec(t: Option) -> Option { diff --git a/crates/wasi-common/cap-std-sync/src/lib.rs b/crates/wasi-common/cap-std-sync/src/lib.rs index 19495e25c8..a924c221e1 100644 --- a/crates/wasi-common/cap-std-sync/src/lib.rs +++ b/crates/wasi-common/cap-std-sync/src/lib.rs @@ -37,6 +37,7 @@ pub mod file; pub mod sched; pub mod stdio; +pub use cap_std::ambient_authority; pub use cap_std::fs::Dir; pub use clocks::clocks_ctx; pub use sched::sched_ctx; @@ -123,5 +124,5 @@ impl WasiCtxBuilder { } pub fn random_ctx() -> Box { - Box::new(unsafe { cap_rand::rngs::OsRng::default() }) + Box::new(cap_rand::rngs::OsRng::default(ambient_authority())) } diff --git a/crates/wasi-common/cap-std-sync/src/sched/unix.rs b/crates/wasi-common/cap-std-sync/src/sched/unix.rs index 7b232a4ed9..a5746a8ce2 100644 --- a/crates/wasi-common/cap-std-sync/src/sched/unix.rs +++ b/crates/wasi-common/cap-std-sync/src/sched/unix.rs @@ -1,6 +1,7 @@ use cap_std::time::Duration; +use io_lifetimes::{AsFd, BorrowedFd}; +use posish::io::{PollFd, PollFdVec, PollFlags}; use std::convert::TryInto; -use std::os::unix::io::{AsRawFd, RawFd}; use wasi_common::{ file::WasiFile, sched::{ @@ -10,27 +11,25 @@ use wasi_common::{ Error, ErrorExt, }; -use poll::{PollFd, PollFlags}; - pub async fn poll_oneoff<'a>(poll: &mut Poll<'a>) -> Result<(), Error> { if poll.is_empty() { return Ok(()); } - let mut pollfds = Vec::new(); + let mut pollfds = PollFdVec::new(); for s in poll.rw_subscriptions() { match s { Subscription::Read(f) => { - let raw_fd = wasi_file_raw_fd(f.file).ok_or( + let fd = wasi_file_fd(f.file).ok_or( Error::invalid_argument().context("read subscription fd downcast failed"), )?; - pollfds.push(unsafe { PollFd::new(raw_fd, PollFlags::POLLIN) }); + pollfds.push(PollFd::from_borrowed_fd(fd, PollFlags::IN)); } Subscription::Write(f) => { - let raw_fd = wasi_file_raw_fd(f.file).ok_or( + let fd = wasi_file_fd(f.file).ok_or( Error::invalid_argument().context("write subscription fd downcast failed"), )?; - pollfds.push(unsafe { PollFd::new(raw_fd, PollFlags::POLLOUT) }); + pollfds.push(PollFd::from_borrowed_fd(fd, PollFlags::OUT)); } Subscription::MonotonicClock { .. } => unreachable!(), } @@ -43,46 +42,39 @@ pub async fn poll_oneoff<'a>(poll: &mut Poll<'a>) -> Result<(), Error> { .try_into() .map_err(|_| Error::overflow().context("poll timeout"))? } else { - libc::c_int::max_value() + std::os::raw::c_int::max_value() }; tracing::debug!( poll_timeout = tracing::field::debug(poll_timeout), poll_fds = tracing::field::debug(&pollfds), "poll" ); - match poll::poll(&mut pollfds, poll_timeout) { + match pollfds.poll(poll_timeout) { Ok(ready) => break ready, - Err(_) => { - let last_err = std::io::Error::last_os_error(); - if last_err.raw_os_error().unwrap() == libc::EINTR { - continue; - } else { - return Err(last_err.into()); - } - } + Err(posish::io::Error::INTR) => continue, + Err(err) => return Err(err.into()), } }; if ready > 0 { for (rwsub, pollfd) in poll.rw_subscriptions().zip(pollfds.into_iter()) { - if let Some(revents) = pollfd.revents() { - let (nbytes, rwsub) = match rwsub { - Subscription::Read(sub) => { - let ready = sub.file.num_ready_bytes().await?; - (std::cmp::max(ready, 1), sub) - } - Subscription::Write(sub) => (0, sub), - _ => unreachable!(), - }; - if revents.contains(PollFlags::POLLNVAL) { - rwsub.error(Error::badf()); - } else if revents.contains(PollFlags::POLLERR) { - rwsub.error(Error::io()); - } else if revents.contains(PollFlags::POLLHUP) { - rwsub.complete(nbytes, RwEventFlags::HANGUP); - } else { - rwsub.complete(nbytes, RwEventFlags::empty()); - }; - } + let revents = pollfd.revents(); + let (nbytes, rwsub) = match rwsub { + Subscription::Read(sub) => { + let ready = sub.file.num_ready_bytes().await?; + (std::cmp::max(ready, 1), sub) + } + Subscription::Write(sub) => (0, sub), + _ => unreachable!(), + }; + if revents.contains(PollFlags::NVAL) { + rwsub.error(Error::badf()); + } else if revents.contains(PollFlags::ERR) { + rwsub.error(Error::io()); + } else if revents.contains(PollFlags::HUP) { + rwsub.complete(nbytes, RwEventFlags::HANGUP); + } else { + rwsub.complete(nbytes, RwEventFlags::empty()); + }; } } else { poll.earliest_clock_deadline() @@ -94,81 +86,17 @@ pub async fn poll_oneoff<'a>(poll: &mut Poll<'a>) -> Result<(), Error> { Ok(()) } -fn wasi_file_raw_fd(f: &dyn WasiFile) -> Option { +fn wasi_file_fd(f: &dyn WasiFile) -> Option> { let a = f.as_any(); if a.is::() { - Some(a.downcast_ref::().unwrap().as_raw_fd()) + Some(a.downcast_ref::().unwrap().as_fd()) } else if a.is::() { - Some(a.downcast_ref::().unwrap().as_raw_fd()) + Some(a.downcast_ref::().unwrap().as_fd()) } else if a.is::() { - Some( - a.downcast_ref::() - .unwrap() - .as_raw_fd(), - ) + Some(a.downcast_ref::().unwrap().as_fd()) } else if a.is::() { - Some( - a.downcast_ref::() - .unwrap() - .as_raw_fd(), - ) + Some(a.downcast_ref::().unwrap().as_fd()) } else { None } } - -mod poll { - use bitflags::bitflags; - use std::convert::TryInto; - use std::os::unix::io::RawFd; - - bitflags! { - pub struct PollFlags: libc::c_short { - const POLLIN = libc::POLLIN; - const POLLPRI = libc::POLLPRI; - const POLLOUT = libc::POLLOUT; - const POLLRDNORM = libc::POLLRDNORM; - const POLLWRNORM = libc::POLLWRNORM; - const POLLRDBAND = libc::POLLRDBAND; - const POLLWRBAND = libc::POLLWRBAND; - const POLLERR = libc::POLLERR; - const POLLHUP = libc::POLLHUP; - const POLLNVAL = libc::POLLNVAL; - } - } - - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] - #[repr(C)] - pub struct PollFd(libc::pollfd); - - impl PollFd { - pub unsafe fn new(fd: RawFd, events: PollFlags) -> Self { - Self(libc::pollfd { - fd, - events: events.bits(), - revents: PollFlags::empty().bits(), - }) - } - - pub fn revents(self) -> Option { - PollFlags::from_bits(self.0.revents) - } - } - - pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result { - let nready = unsafe { - libc::poll( - fds.as_mut_ptr() as *mut libc::pollfd, - fds.len() as libc::nfds_t, - timeout, - ) - }; - if nready == -1 { - Err(std::io::Error::last_os_error()) - } else { - // When poll doesn't fail, its return value is a non-negative int, which will - // always be convertable to usize, so we can unwrap() here. - Ok(nready.try_into().unwrap()) - } - } -} diff --git a/crates/wasi-common/cap-std-sync/src/sched/windows.rs b/crates/wasi-common/cap-std-sync/src/sched/windows.rs index 41f3f1dda3..e4755093c5 100644 --- a/crates/wasi-common/cap-std-sync/src/sched/windows.rs +++ b/crates/wasi-common/cap-std-sync/src/sched/windows.rs @@ -9,6 +9,7 @@ // taken the time to improve it. See bug #2880. use anyhow::Context; +use io_lifetimes::AsHandle; use std::ops::Deref; use std::os::windows::io::{AsRawHandle, RawHandle}; use std::sync::mpsc::{self, Receiver, RecvTimeoutError, Sender, TryRecvError}; @@ -145,24 +146,28 @@ pub fn wasi_file_raw_handle(f: &dyn WasiFile) -> Option { Some( a.downcast_ref::() .unwrap() + .as_handle() .as_raw_handle(), ) } else if a.is::() { Some( a.downcast_ref::() .unwrap() + .as_handle() .as_raw_handle(), ) } else if a.is::() { Some( a.downcast_ref::() .unwrap() + .as_handle() .as_raw_handle(), ) } else if a.is::() { Some( a.downcast_ref::() .unwrap() + .as_handle() .as_raw_handle(), ) } else { diff --git a/crates/wasi-common/cap-std-sync/src/stdio.rs b/crates/wasi-common/cap-std-sync/src/stdio.rs index 6de8a98afa..fbb0ed3df5 100644 --- a/crates/wasi-common/cap-std-sync/src/stdio.rs +++ b/crates/wasi-common/cap-std-sync/src/stdio.rs @@ -1,16 +1,17 @@ use crate::file::convert_systimespec; use fs_set_times::SetTimes; +use io_lifetimes::AsFilelike; use std::any::Any; use std::convert::TryInto; +use std::fs::File; use std::io; use std::io::{Read, Write}; use system_interface::io::ReadReady; #[cfg(unix)] -use std::os::unix::io::{AsRawFd, RawFd}; +use io_lifetimes::{AsFd, BorrowedFd}; #[cfg(windows)] -use std::os::windows::io::{AsRawHandle, RawHandle}; -use unsafe_io::AsUnsafeFile; +use io_lifetimes::{AsHandle, BorrowedHandle}; use wasi_common::{ file::{Advice, FdFlags, FileType, Filestat, WasiFile}, Error, ErrorExt, @@ -43,7 +44,7 @@ impl WasiFile for Stdin { Err(Error::badf()) } async fn get_filestat(&self) -> Result { - let meta = self.0.as_file_view().metadata()?; + let meta = self.0.as_filelike_view::().metadata()?; Ok(Filestat { device_id: 0, inode: 0, @@ -65,7 +66,7 @@ impl WasiFile for Stdin { Err(Error::badf()) } async fn read_vectored<'a>(&self, bufs: &mut [io::IoSliceMut<'a>]) -> Result { - let n = self.0.as_file_view().read_vectored(bufs)?; + let n = self.0.as_filelike_view::().read_vectored(bufs)?; Ok(n.try_into().map_err(|_| Error::range())?) } async fn read_vectored_at<'a>( @@ -111,15 +112,15 @@ impl WasiFile for Stdin { } } #[cfg(windows)] -impl AsRawHandle for Stdin { - fn as_raw_handle(&self) -> RawHandle { - self.0.as_raw_handle() +impl AsHandle for Stdin { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.0.as_handle() } } #[cfg(unix)] -impl AsRawFd for Stdin { - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() +impl AsFd for Stdin { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() } } @@ -146,7 +147,7 @@ macro_rules! wasi_file_write_impl { Err(Error::badf()) } async fn get_filestat(&self) -> Result { - let meta = self.0.as_file_view().metadata()?; + let meta = self.0.as_filelike_view::().metadata()?; Ok(Filestat { device_id: 0, inode: 0, @@ -181,7 +182,7 @@ macro_rules! wasi_file_write_impl { Err(Error::badf()) } async fn write_vectored<'a>(&self, bufs: &[io::IoSlice<'a>]) -> Result { - let n = self.0.as_file_view().write_vectored(bufs)?; + let n = self.0.as_filelike_view::().write_vectored(bufs)?; Ok(n.try_into().map_err(|c| Error::range().context(c))?) } async fn write_vectored_at<'a>( @@ -217,15 +218,15 @@ macro_rules! wasi_file_write_impl { } } #[cfg(windows)] - impl AsRawHandle for $ty { - fn as_raw_handle(&self) -> RawHandle { - self.0.as_raw_handle() + impl AsHandle for $ty { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.0.as_handle() } } #[cfg(unix)] - impl AsRawFd for $ty { - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() + impl AsFd for $ty { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() } } }; diff --git a/crates/wasi-common/src/snapshots/preview_1.rs b/crates/wasi-common/src/snapshots/preview_1.rs index c05727a735..fd726f43d3 100644 --- a/crates/wasi-common/src/snapshots/preview_1.rs +++ b/crates/wasi-common/src/snapshots/preview_1.rs @@ -111,83 +111,78 @@ impl TryFrom for types::Errno { type Error = Error; fn try_from(err: std::io::Error) -> Result { #[cfg(unix)] - fn raw_error_code(code: i32) -> Option { - match code { - libc::EPIPE => Some(types::Errno::Pipe), - libc::EPERM => Some(types::Errno::Perm), - libc::ENOENT => Some(types::Errno::Noent), - libc::ENOMEM => Some(types::Errno::Nomem), - libc::E2BIG => Some(types::Errno::TooBig), - libc::EIO => Some(types::Errno::Io), - libc::EBADF => Some(types::Errno::Badf), - libc::EBUSY => Some(types::Errno::Busy), - libc::EACCES => Some(types::Errno::Acces), - libc::EFAULT => Some(types::Errno::Fault), - libc::ENOTDIR => Some(types::Errno::Notdir), - libc::EISDIR => Some(types::Errno::Isdir), - libc::EINVAL => Some(types::Errno::Inval), - libc::EEXIST => Some(types::Errno::Exist), - libc::EFBIG => Some(types::Errno::Fbig), - libc::ENOSPC => Some(types::Errno::Nospc), - libc::ESPIPE => Some(types::Errno::Spipe), - libc::EMFILE => Some(types::Errno::Mfile), - libc::EMLINK => Some(types::Errno::Mlink), - libc::ENAMETOOLONG => Some(types::Errno::Nametoolong), - libc::ENFILE => Some(types::Errno::Nfile), - libc::ENOTEMPTY => Some(types::Errno::Notempty), - libc::ELOOP => Some(types::Errno::Loop), - libc::EOVERFLOW => Some(types::Errno::Overflow), - libc::EILSEQ => Some(types::Errno::Ilseq), - libc::ENOTSUP => Some(types::Errno::Notsup), + fn raw_error_code(err: &std::io::Error) -> Option { + use posish::io::Error; + match Error::from_io_error(err) { + Some(Error::PIPE) => Some(types::Errno::Pipe), + Some(Error::PERM) => Some(types::Errno::Perm), + Some(Error::NOENT) => Some(types::Errno::Noent), + Some(Error::NOMEM) => Some(types::Errno::Nomem), + Some(Error::TOOBIG) => Some(types::Errno::TooBig), + Some(Error::IO) => Some(types::Errno::Io), + Some(Error::BADF) => Some(types::Errno::Badf), + Some(Error::BUSY) => Some(types::Errno::Busy), + Some(Error::ACCES) => Some(types::Errno::Acces), + Some(Error::FAULT) => Some(types::Errno::Fault), + Some(Error::NOTDIR) => Some(types::Errno::Notdir), + Some(Error::ISDIR) => Some(types::Errno::Isdir), + Some(Error::INVAL) => Some(types::Errno::Inval), + Some(Error::EXIST) => Some(types::Errno::Exist), + Some(Error::FBIG) => Some(types::Errno::Fbig), + Some(Error::NOSPC) => Some(types::Errno::Nospc), + Some(Error::SPIPE) => Some(types::Errno::Spipe), + Some(Error::MFILE) => Some(types::Errno::Mfile), + Some(Error::MLINK) => Some(types::Errno::Mlink), + Some(Error::NAMETOOLONG) => Some(types::Errno::Nametoolong), + Some(Error::NFILE) => Some(types::Errno::Nfile), + Some(Error::NOTEMPTY) => Some(types::Errno::Notempty), + Some(Error::LOOP) => Some(types::Errno::Loop), + Some(Error::OVERFLOW) => Some(types::Errno::Overflow), + Some(Error::ILSEQ) => Some(types::Errno::Ilseq), + Some(Error::NOTSUP) => Some(types::Errno::Notsup), _ => None, } } #[cfg(windows)] - fn raw_error_code(code: i32) -> Option { + fn raw_error_code(err: &std::io::Error) -> Option { use winapi::shared::winerror; - match code as u32 { - winerror::ERROR_BAD_ENVIRONMENT => Some(types::Errno::TooBig), - winerror::ERROR_FILE_NOT_FOUND => Some(types::Errno::Noent), - winerror::ERROR_PATH_NOT_FOUND => Some(types::Errno::Noent), - winerror::ERROR_TOO_MANY_OPEN_FILES => Some(types::Errno::Nfile), - winerror::ERROR_ACCESS_DENIED => Some(types::Errno::Acces), - winerror::ERROR_SHARING_VIOLATION => Some(types::Errno::Acces), - winerror::ERROR_PRIVILEGE_NOT_HELD => Some(types::Errno::Perm), - winerror::ERROR_INVALID_HANDLE => Some(types::Errno::Badf), - winerror::ERROR_INVALID_NAME => Some(types::Errno::Noent), - winerror::ERROR_NOT_ENOUGH_MEMORY => Some(types::Errno::Nomem), - winerror::ERROR_OUTOFMEMORY => Some(types::Errno::Nomem), - winerror::ERROR_DIR_NOT_EMPTY => Some(types::Errno::Notempty), - winerror::ERROR_NOT_READY => Some(types::Errno::Busy), - winerror::ERROR_BUSY => Some(types::Errno::Busy), - winerror::ERROR_NOT_SUPPORTED => Some(types::Errno::Notsup), - winerror::ERROR_FILE_EXISTS => Some(types::Errno::Exist), - winerror::ERROR_BROKEN_PIPE => Some(types::Errno::Pipe), - winerror::ERROR_BUFFER_OVERFLOW => Some(types::Errno::Nametoolong), - winerror::ERROR_NOT_A_REPARSE_POINT => Some(types::Errno::Inval), - winerror::ERROR_NEGATIVE_SEEK => Some(types::Errno::Inval), - winerror::ERROR_DIRECTORY => Some(types::Errno::Notdir), - winerror::ERROR_ALREADY_EXISTS => Some(types::Errno::Exist), - winerror::ERROR_STOPPED_ON_SYMLINK => Some(types::Errno::Loop), - winerror::ERROR_DIRECTORY_NOT_SUPPORTED => Some(types::Errno::Isdir), + match err.raw_os_error().map(|code| code as u32) { + Some(winerror::ERROR_BAD_ENVIRONMENT) => Some(types::Errno::TooBig), + Some(winerror::ERROR_FILE_NOT_FOUND) => Some(types::Errno::Noent), + Some(winerror::ERROR_PATH_NOT_FOUND) => Some(types::Errno::Noent), + Some(winerror::ERROR_TOO_MANY_OPEN_FILES) => Some(types::Errno::Nfile), + Some(winerror::ERROR_ACCESS_DENIED) => Some(types::Errno::Acces), + Some(winerror::ERROR_SHARING_VIOLATION) => Some(types::Errno::Acces), + Some(winerror::ERROR_PRIVILEGE_NOT_HELD) => Some(types::Errno::Perm), + Some(winerror::ERROR_INVALID_HANDLE) => Some(types::Errno::Badf), + Some(winerror::ERROR_INVALID_NAME) => Some(types::Errno::Noent), + Some(winerror::ERROR_NOT_ENOUGH_MEMORY) => Some(types::Errno::Nomem), + Some(winerror::ERROR_OUTOFMEMORY) => Some(types::Errno::Nomem), + Some(winerror::ERROR_DIR_NOT_EMPTY) => Some(types::Errno::Notempty), + Some(winerror::ERROR_NOT_READY) => Some(types::Errno::Busy), + Some(winerror::ERROR_BUSY) => Some(types::Errno::Busy), + Some(winerror::ERROR_NOT_SUPPORTED) => Some(types::Errno::Notsup), + Some(winerror::ERROR_FILE_EXISTS) => Some(types::Errno::Exist), + Some(winerror::ERROR_BROKEN_PIPE) => Some(types::Errno::Pipe), + Some(winerror::ERROR_BUFFER_OVERFLOW) => Some(types::Errno::Nametoolong), + Some(winerror::ERROR_NOT_A_REPARSE_POINT) => Some(types::Errno::Inval), + Some(winerror::ERROR_NEGATIVE_SEEK) => Some(types::Errno::Inval), + Some(winerror::ERROR_DIRECTORY) => Some(types::Errno::Notdir), + Some(winerror::ERROR_ALREADY_EXISTS) => Some(types::Errno::Exist), + Some(winerror::ERROR_STOPPED_ON_SYMLINK) => Some(types::Errno::Loop), + Some(winerror::ERROR_DIRECTORY_NOT_SUPPORTED) => Some(types::Errno::Isdir), _ => None, } } - match err.raw_os_error() { - Some(code) => match raw_error_code(code) { - Some(errno) => Ok(errno), - None => { - Err(anyhow::anyhow!(err).context(format!("Unknown raw OS error: {}", code))) - } - }, + match raw_error_code(&err) { + Some(errno) => Ok(errno), None => match err.kind() { std::io::ErrorKind::NotFound => Ok(types::Errno::Noent), std::io::ErrorKind::PermissionDenied => Ok(types::Errno::Perm), std::io::ErrorKind::AlreadyExists => Ok(types::Errno::Exist), std::io::ErrorKind::InvalidInput => Ok(types::Errno::Ilseq), - k => Err(anyhow::anyhow!(err) - .context(format!("No raw OS error. Unhandled kind: {:?}", k))), + _ => Err(anyhow::anyhow!(err).context(format!("Unknown OS error"))), }, } } diff --git a/crates/wasi-common/tokio/Cargo.toml b/crates/wasi-common/tokio/Cargo.toml index c95912f63f..abfdc74359 100644 --- a/crates/wasi-common/tokio/Cargo.toml +++ b/crates/wasi-common/tokio/Cargo.toml @@ -15,20 +15,18 @@ wasi-common = { path = "../", version = "0.28.0" } wasi-cap-std-sync = { path = "../cap-std-sync", version = "0.28.0" } wiggle = { path = "../../wiggle", version = "0.28.0" } tokio = { version = "1.8.0", features = [ "rt", "fs", "time", "io-util", "net", "io-std", "rt-multi-thread"] } -cap-std = "0.13.7" -cap-fs-ext = "0.13.7" -cap-time-ext = "0.13.7" -fs-set-times = "0.3.1" -unsafe-io = "0.6.5" -system-interface = { version = "0.6.4", features = ["cap_std_impls"] } +cap-std = "0.16.0" +cap-fs-ext = "0.16.0" +cap-time-ext = "0.16.0" +fs-set-times = "0.6.0" +system-interface = { version = "0.8.0", features = ["cap_std_impls"] } tracing = "0.1.19" bitflags = "1.2" anyhow = "1" +io-lifetimes = "0.2.0" [target.'cfg(unix)'.dependencies] -libc = "0.2" -posish = "0.6.1" - +posish = "0.16.0" [target.'cfg(windows)'.dependencies] winapi = "0.3" @@ -38,4 +36,4 @@ lazy_static = "1.4" tempfile = "3.1.0" tokio = { version = "1.8.0", features = [ "macros" ] } anyhow = "1" -cap-tempfile = "0.13.7" +cap-tempfile = "0.16.0" diff --git a/crates/wasi-common/tokio/src/dir.rs b/crates/wasi-common/tokio/src/dir.rs index a70b44e182..f95e61219e 100644 --- a/crates/wasi-common/tokio/src/dir.rs +++ b/crates/wasi-common/tokio/src/dir.rs @@ -126,13 +126,15 @@ impl WasiDir for Dir { #[cfg(test)] mod test { use super::Dir; + use cap_std::ambient_authority; + #[tokio::test(flavor = "multi_thread")] async fn scratch_dir() { let tempdir = tempfile::Builder::new() .prefix("cap-std-sync") .tempdir() .expect("create temporary dir"); - let preopen_dir = unsafe { cap_std::fs::Dir::open_ambient_dir(tempdir.path()) } + let preopen_dir = cap_std::fs::Dir::open_ambient_dir(tempdir.path(), ambient_authority()) .expect("open ambient temporary dir"); let preopen_dir = Dir::from_cap_std(preopen_dir); wasi_common::WasiDir::open_dir(&preopen_dir, false, ".") @@ -165,7 +167,7 @@ mod test { .prefix("cap-std-sync") .tempdir() .expect("create temporary dir"); - let preopen_dir = unsafe { cap_std::fs::Dir::open_ambient_dir(tempdir.path()) } + let preopen_dir = cap_std::fs::Dir::open_ambient_dir(tempdir.path(), ambient_authority()) .expect("open ambient temporary dir"); let preopen_dir = Dir::from_cap_std(preopen_dir); diff --git a/crates/wasi-common/tokio/src/file.rs b/crates/wasi-common/tokio/src/file.rs index 45e684e559..3a8699e1e9 100644 --- a/crates/wasi-common/tokio/src/file.rs +++ b/crates/wasi-common/tokio/src/file.rs @@ -1,8 +1,10 @@ use crate::block_on_dummy_executor; +#[cfg(not(windows))] +use io_lifetimes::AsFd; +#[cfg(windows)] +use io_lifetimes::{AsHandle, BorrowedHandle}; use std::any::Any; use std::io; -#[cfg(windows)] -use std::os::windows::io::{AsRawHandle, RawHandle}; use wasi_common::{ file::{Advice, FdFlags, FileType, Filestat, WasiFile}, Error, @@ -118,9 +120,9 @@ macro_rules! wasi_file_impl { // mutability to let it own the `Inner`, we are depending on the `&mut self` bound on this // async method to ensure this is the only Future which can access the RawFd during the // lifetime of the AsyncFd. + use std::os::unix::io::AsRawFd; use tokio::io::{unix::AsyncFd, Interest}; - use unsafe_io::os::posish::AsRawFd; - let rawfd = self.0.as_raw_fd(); + let rawfd = self.0.as_fd().as_raw_fd(); match AsyncFd::with_interest(rawfd, Interest::READABLE) { Ok(asyncfd) => { let _ = asyncfd.readable().await?; @@ -148,9 +150,9 @@ macro_rules! wasi_file_impl { // mutability to let it own the `Inner`, we are depending on the `&mut self` bound on this // async method to ensure this is the only Future which can access the RawFd during the // lifetime of the AsyncFd. + use std::os::unix::io::AsRawFd; use tokio::io::{unix::AsyncFd, Interest}; - use unsafe_io::os::posish::AsRawFd; - let rawfd = self.0.as_raw_fd(); + let rawfd = self.0.as_fd().as_raw_fd(); match AsyncFd::with_interest(rawfd, Interest::WRITABLE) { Ok(asyncfd) => { let _ = asyncfd.writable().await?; @@ -172,9 +174,9 @@ macro_rules! wasi_file_impl { } } #[cfg(windows)] - impl AsRawHandle for $ty { - fn as_raw_handle(&self) -> RawHandle { - self.0.as_raw_handle() + impl AsHandle for $ty { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.0.as_handle() } } }; diff --git a/crates/wasi-common/tokio/src/sched/windows.rs b/crates/wasi-common/tokio/src/sched/windows.rs index 90b33aeb47..b6849c6216 100644 --- a/crates/wasi-common/tokio/src/sched/windows.rs +++ b/crates/wasi-common/tokio/src/sched/windows.rs @@ -1,4 +1,5 @@ use crate::block_on_dummy_executor; +use io_lifetimes::AsHandle; use std::os::windows::io::{AsRawHandle, RawHandle}; use wasi_cap_std_sync::sched::windows::poll_oneoff_; use wasi_common::{file::WasiFile, sched::Poll, Error}; @@ -21,24 +22,28 @@ fn wasi_file_raw_handle(f: &dyn WasiFile) -> Option { Some( a.downcast_ref::() .unwrap() + .as_handle() .as_raw_handle(), ) } else if a.is::() { Some( a.downcast_ref::() .unwrap() + .as_handle() .as_raw_handle(), ) } else if a.is::() { Some( a.downcast_ref::() .unwrap() + .as_handle() .as_raw_handle(), ) } else if a.is::() { Some( a.downcast_ref::() .unwrap() + .as_handle() .as_raw_handle(), ) } else { diff --git a/crates/wasi-common/tokio/tests/poll_oneoff.rs b/crates/wasi-common/tokio/tests/poll_oneoff.rs index 4d8c67c225..9ba85f6dee 100644 --- a/crates/wasi-common/tokio/tests/poll_oneoff.rs +++ b/crates/wasi-common/tokio/tests/poll_oneoff.rs @@ -14,7 +14,8 @@ const TIMEOUT: Duration = Duration::from_millis(200); // Required for slow execu async fn empty_file_readable() -> Result<(), Error> { let clocks = clocks_ctx(); - let workspace = unsafe { cap_tempfile::tempdir().expect("create tempdir") }; + let workspace = + cap_tempfile::tempdir(cap_tempfile::ambient_authority()).expect("create tempdir"); workspace.create_dir("d").context("create dir")?; let d = workspace.open_dir("d").context("open dir")?; let d = Dir::from_cap_std(d); @@ -66,7 +67,8 @@ async fn empty_file_readable() -> Result<(), Error> { async fn empty_file_writable() -> Result<(), Error> { let clocks = clocks_ctx(); - let workspace = unsafe { cap_tempfile::tempdir().expect("create tempdir") }; + let workspace = + cap_tempfile::tempdir(cap_tempfile::ambient_authority()).expect("create tempdir"); workspace.create_dir("d").context("create dir")?; let d = workspace.open_dir("d").context("open dir")?; let d = Dir::from_cap_std(d); diff --git a/src/commands/run.rs b/src/commands/run.rs index fe4400182d..577efd4f20 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -11,7 +11,7 @@ use std::{ }; use structopt::{clap::AppSettings, StructOpt}; use wasmtime::{Engine, Func, Linker, Module, Store, Trap, Val, ValType}; -use wasmtime_wasi::sync::{Dir, WasiCtxBuilder}; +use wasmtime_wasi::sync::{ambient_authority, Dir, WasiCtxBuilder}; #[cfg(feature = "wasi-nn")] use wasmtime_wasi_nn::WasiNnCtx; @@ -215,7 +215,7 @@ impl RunCommand { for dir in self.dirs.iter() { preopen_dirs.push(( dir.clone(), - unsafe { Dir::open_ambient_dir(dir) } + Dir::open_ambient_dir(dir, ambient_authority()) .with_context(|| format!("failed to open directory '{}'", dir))?, )); } @@ -223,7 +223,7 @@ impl RunCommand { for (guest, host) in self.map_dirs.iter() { preopen_dirs.push(( guest.clone(), - unsafe { Dir::open_ambient_dir(host) } + Dir::open_ambient_dir(host, ambient_authority()) .with_context(|| format!("failed to open directory '{}'", host))?, )); }