Files
wazero/internal/testing/fs/fs.go
Crypt Keeper 105cdcdef7 cli: rewrites compositeFS to syscallfs and adds read-only (:ro) mounts (#1030)
This rewrites compositeFS to syscallfs.FS following wasi-sdk preopen
rules. Notably, this allows use of read-only mounts now.

For example,
```bash
$ GOOS=js GOARCH=wasm bin/go test -c -o template.wasm text/template
$ wazero run -mount=src/text/template:/ -mount=/tmp:/tmp template.wasm -test.v
=== RUN   TestExecute
--- PASS: TestExecute (0.07s)
--snip--
```

This is the first step to native WASI handling of multiple pre-opens.
After this change, it is still the case that there's only one pre-open
FD visible to wasm. A later change will make it possible for WASI to see
multiple pre-opens while `GOOS=js` which doesn't use preopens, remains
on a rootFS.

A future PR may need to add a CLI flag to disable escaping directories,
(e.g. make ../.. EINVAL), similar to `fs.FS` in Go. The simplest way to
allow this is to use a host-side RootFS even in WASI, and wrap that with
a `syscallfs` filename filter.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-13 15:50:11 +08:00

30 lines
887 B
Go

package testfs
import "io/fs"
// compile-time check to ensure File implements fs.File
var _ fs.File = &File{}
// compile-time check to ensure FS implements fs.FS
var _ fs.FS = &FS{}
// FS emulates fs.FS. Note: the path (map key) cannot begin with "/"!
type FS map[string]*File
// Open implements the same method as documented on fs.FS, except it doesn't
// validate the path.
func (f FS) Open(name string) (fs.File, error) {
if file, ok := f[name]; !ok {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
} else {
return file, nil
}
}
type File struct{ CloseErr error }
func (f *File) Close() error { return f.CloseErr }
func (f *File) Stat() (fs.FileInfo, error) { return nil, nil }
func (f *File) Read(_ []byte) (int, error) { return 0, nil }
func (f *File) Seek(_ int64, _ int) (int64, error) { return 0, nil }