This changes file descriptors from uint32 to int32 and the
corresponding file table to reject negative values. This ensures
invalid values aren't mistaken for very large descriptor entries, which
can use a lot of memory as the table implementation isn't designed to
be sparse.
See https://pubs.opengroup.org/onlinepubs/9699919799/functions/dirfd.html#tag_16_90
Signed-off-by: Adrian Cole <adrian@tetrate.io>
The PR introduces the `platform.Select()` API, wrapping `select(2)` on POSIX and emulated in some cases on Windows. RATIONALE.md contains a full explanation of the approach followed in `poll_oneoff` to handle Stdin and the other types of file descriptors, and the clock subscriptions.
It also introduces an abstraction (`StdioFilePoller`) to allow the simulation of different scenarios (waiting for input, input ready, timeout expired, etc.) when unit-testing interactive input.
This closes#1317.
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
Ensure that stdio device modes are consistent with the given
file descriptors by stat'ing, instead of returning mocks.
* Use `Stat()` on `poll_oneoff()` too, instead of `IsTerminal()`,
thus avoiding a useless syscall.
* Delete leftover type decl `fileModeStat`.
* Remove IsPlatform()
* Propagate error when Stat() fails
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This forces all syscall functions, notably filesystem, to return numeric
codes as opposed to mapping in two different areas. The result of this
change is better consolidation in call sites of `sysfs.FS`, while
further refactoring is needed to address consolidation of file errors.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
wasi-testsuite changed its mind on pre-open WebAssembly/wasi-testsuite#66
they also now explicitly forbid paths being passed in with a leading slash. Even when the config bug on WebAssembly/wasi-testsuite#67 is finished, this requires discussion if we want to EPERM on that.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This forces all syscall functions, notably filesystem, to return numeric
codes as opposed to mapping in two different areas. The result of this
change is better consolidation in call sites of `sysfs.FS`, while
further refactoring is needed to address consolidation of file errors.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
wasi_snapshot_preview1 recently requires fd_readdir to return actual
inode values. On zero, wasi-libc will call fdstat to retrieve them.
This introduces our own `platform.Dirent` type and `Readdir` function
which a later change will allow fetching of inodes.
See https://github.com/WebAssembly/wasi-libc/pull/345
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This allows rewinding a directory by specifying the cookie 0, after
already scrolling a directory. This allows zig and clang functionality
to work which expect this.
This also fixes the case where a directory was allowed to be seeked.
This is prohibited by the current version of wasi-testsuite.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Takeshi Yoneda <takeshi@tetrate.io>
This allows wasi to see mounts as individual preopens instead of
virtualized under a root. (GOOS=js doesn't use pre-opens so it still
sees a virtual root). This allows us to progress wasi-testsuite rust
tests, but acknowledges a current glitch in zig support, which is
tracked separately as #1077
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This decouples sysfs.FS from fs.FS by introducing a temporary type
FSHolder, which will be removed when we top-level FSConfig (shortly).
This further reduces complexity by consolidating guest path
configuration into the only type that uses it: CompositeFS.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
It will help for us to rename earlier vs later, and syscallfs will be
laborious, especially after we introduce an FSConfig type and need to
declare a method name that differentiates from normal fs.FS. e.g. WithFS
vs WithSysFS reads nicer than WithSyscallFS, and meanwhile sys is
already a public package.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This reduces some boilerplate by extracting UnimplementedFS from the
existing FS implementations, such that it returns ENOSYS. This also
removes inconsistency where some methods on FS returned syscall.Errno
and others PathError.
Note: this doesn't get rid of all PathError, yet. We still need to
create a syscallfs.File type which would be able to do that. This is
just one preliminary cleanup before refactoring out the `fs.FS`
embedding from `syscallfs.DS`.
P.S. naming convention is arbitrary, so I took UnimplementedXXX from
grpc. This pattern is used a lot of places, also proxy-wasm-go-sdk, e.g.
`DefaultVMContext`.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This prepares for pseudo-root when the CLI doesn't provide one by
improving the error messages in general, as well being consistent about
parameter order.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
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>
This adds FS.Path which holds the pre-open path currently only used in
WASI. It also fixes a TODO where we didn't know for sure if the FD
parameter for `path_` functions must always be a pre-open. The TL;DR; is
that usually it is, but it may not be (e.g. in our zig-cc example we can
see any directory FD, not just pre-opens).
Finally, this fixes a bug in our path resolution where we mistook paths
like "foo/foo" for "foo" because we only considered basenames instead of
the full path from the pre-open root.
This also makes pre-open directory lookup lazy because I noticed in
Trivy specifically, this is unnecessary for us to do eagerly, as they
change the FS at runtime per-call. In other words, any value from init
time is invalid later.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This consolidates internal code to syscallfs, which removes the fs.FS
specific path rules, except when adapting one to syscallfs. For example,
this allows the underlying filesystem to decide if relative paths are
supported or not, as well any EINVAL related concerns.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds writefs.FS, allowing functions to create and delete files.
This begins by implementing them on `GOARCH=js GOOS=wasm`. The current
status is a lot farther than before, even if completing write on WASI is
left for a later PR (possibly by another volunteer).
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Allows wasm to close stdio file descriptors
This allows wasm to close stdio file descriptors such as STDOUT(1).
This will not close the underlying host resource as that would break a
lot of folks doing logging to the console.
Fixes#953
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This uses ioctl syscalls or appropriate alternative, to detect if
stdin/out/err are character devices or not. This caches the result, to
ensure performance is ok at runtime as executing stat can approach
microsecond overhead.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This removes the ability to override the current file system with Go
context, allowing us to simplify common paths and improve performance.
The context override was only used once in GitHub, in Trivy, and we
found another way to do that without it.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
At the moment, the only pre-open support we have is the file system
itself (root a.k.a. / or file-descriptor 3). We may in the future add
the ability to pre-open sockets, but in any case, this is where we are
today.
This change hardens logic around fd_preXXX functions, ensuring they only
work on actual pre-opens. This also fixes the path returned in filestat
as we sometimes returned a full path, when typically the basename is the
only part that can be returned.
Signed-off-by: Adrian Cole <adrian@tetrate.io>