Accessing file system with Go WASI throws "Bad file number" error

238 views Asked by At

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.

1

There are 1 answers

0
Christian González Di Antonio On

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: