I'm trying out Go's newly added support for the WebAssembly System Interface (WASI). I'm attempting to access OS resources, such as the file system.
package main
import "os"
func main() {
err := os.WriteFile("text.txt", []byte("Hello World"), 0644)
if err != nil {
panic(err)
}
}
This code, of course, runs successfully when the target is my OS (Windows WSL2 Ubuntu 20.04). However, when I set the target as GOARCH=wasm GOOS=wasip1, the following error is thrown:
panic: open text.txt: Bad file number
goroutine 1 [running]:
main.main()
/home/optimuseprime/Projects/go-wasi/main.go:8 +0x7
I'm using the WasmEdge runtime to execute the .wasm executable, however I have also attempted to execute it with Wasmtime and Wazero and the same error appears. I use the command wasmedge --dir .:. main.wasm.
To ensure the Go code is at fault and not my runtime configuration, I also recreated the same program with Rust, which executes correctly with the same WasmEdge command.
use std::fs::File;
use std::io::Write;
use std::path::Path;
fn main() {
let mut f = File::create(Path::new("test.txt")).unwrap();
f.write("Hello, world!".as_bytes()).unwrap();
}
I'm aware Rust's support for WASI is better than Go's. Does Go perhaps not support accessing the file system from WASI?
The only other reference to this error I found is a Go Github issue, but it doesn't seem to solve the problem.
I also do not entirely understand the meaning of Bad file number. The error is quite ambigious.
Previously when I tried creating an HTTP server with Go/WASI stealthrocket/net and executed it with WasmEdge, everything worked, so I'm not sure why accessing the file system does not.
It is not a Golang/Rust problem, it is about WASI Limitations, see the "Limitations" section here https://go.dev/blog/wasi, they mention this https://github.com/stealthrocket/net and an alternative, and these could be implemented using "Host Functions" which is a workaround until WASI implement access to the network and filesystem.
Here is the Fs's proposal https://github.com/WebAssembly/wasi-filesystem and here is the sockets' proposal https://github.com/WebAssembly/wasi-sockets
Some of the WASM "frameworks" have these workarounds that have already been implemented, see Wasmtime, Wazero, WasmEdge and Wasmer among others.
Maybe these could help you: