I wrote a simple wasmer-wasi example that reads directory entries but it always fails.
#[no_mangle]
pub fn start() {
std::fs::read_dir("/").unwrap();
}
use wasmer::{Instance, Module, Store};
use wasmer_wasi::WasiState;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let wasm = std::fs::read("target/wasm32-wasi/debug/wasi_fs_example.wasm")?;
let store = Store::default();
let module = Module::new(&store, wasm)?;
let mut wasi_env = WasiState::new("wasi_fs_example")
.preopen_dir("target")?
.finalize()?;
let import_object = wasi_env.import_object(&module)?;
let instance = Instance::new(&module, &import_object)?;
let start = instance.exports.get_function("start")?;
start.call(&[])?;
Ok(())
}
This produce the error while running:
cargo build -p wasi_fs_example --target wasm32-wasi
cargo run -p runner
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "failed to find a pre-opened file descriptor through which \"/\" could be opened" }', wasi_fs_example/src/lib.rs:6:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Full source code of the example is located here. Why doesn't it work?
Currently in Rust we can really only create WASI binaries, not libraries. WASI only works for the duration of a main function that needs to be there. Calling the wasi functions from anywhere else segfaults because libpreopen isn't initialized.
So to summarize, how to fix this currently:
lib.crate-type
at allsrc/main.rs
, notsrc/lib.rs
#![no_main]
at the top of thesrc/main.rs
RUSTFLAGS="-Z wasi-exec-model=reactor" cargo +nightly build --target wasm32-wasi
_initialize
before anything elsehttps://github.com/WebAssembly/WASI/issues/24
https://github.com/rust-lang/rust/pull/79997
In my case:
wasi_fs_example/src/main.rs
:runner/src/main.rs
: