This implements `path_filestat_set_times` which is the last remaining filesystem function in wasi we formerly stubbed.
Other minor changes:
* this removes all places we import alias path as pathutil, introducing a utility function `joinPath` where that was used to reduce name conflicts.
* this fixes places where we used different variable names for the same parameter between main and test source.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
platform: Allows sysfs to implement utimesns natively
This moves away from `syscall.UtimesNano` as it has intentionally
avoided common features in POSIX, such as handling UTIME_NOW and
UTIME_OMIT. When we eventually expose this API, users will be free to
override `UTIME_NOW` with a fake clock, possibly the same that was
supplied to wazero's `ModuleConfig`.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This implements `platform.UtimesFile` which is similar to futimes.
Before, we were using path-based functionality even though the call site
was for a file descriptor.
Note: right now, there's no obvious code in Go to invoke the `futimens`
syscall. This means non-windows isn't implemented at nanos granularity,
so ends up falling back to the path based option.
Finally, this removes tests for the seldom supported updates with
negative epoch time. There's little impact to this as setting times on
files before 1970 isn't a typical use case.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This finishes the last remaining syscalls in `GOOS=js`. After this is
merged, further bugs are easier to hunt down as we know ENOSYS is not
expected on writeable file systems.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This implements the last remaining link functions using the same logic
as WASI. In doing so, this changes the signature for FS.ReadLink to be
more similar to the rest of the functions. Particularly, it stops
reading the result into a buffer.
After this, the only syscalls left to implement in gojs are chown.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
In previous releases, passing a `nil` value as an FS config
did not cause any error. However, in 1.0.0-rc.1 this leads
to the creation of an invalid `adapter{fs: nil}`, which
eventually leads to a panic (nil):
(f *FileEntry) Stat(st *platform.Stat_t) =>
(r *lazyDir) file() =>
r.fs.OpenFile(".", os.O_RDONLY, 0)
with fs == nil
The backwards-compatible fix is to make Adapt()
return UnimplementedFS, and ensuring `nil` is a valid value
that config is able to handle.
However, we may want to consider returning an error somewhere,
because configuring a nil FS may be unintended.
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This adds a wazero adapter which passes wasi-testsuite 100pct on darwin,
linux and windows. While the main change was adding inodes to the wasi
`fd_readdir` dirents, there was a lot of incidental work needed.
Most of the work was troubleshooting in nature, around windows
specifically, but also wrapping of files. This backfills a lot of tests
and reworked how wrapping works, particularly around windows.
To accommodate this, we drop `os.File` special casing except for
`sysfs.DirFS`
Signed-off-by: Adrian Cole <adrian@tetrate.io>
gojs: implements lstat
This implements platform.Lstat and uses it in GOOS=js. Notably,
directory listings need to run lstat on their entries to get the correct
inodes back. In GOOS=js, directories are a fan-out of names, then lstat.
This also fixes stat for inodes on directories. We were missing a test
so we didn't know it was broken on windows. The approach used now is
reliable on go 1.20, and we should suggest anyone using windows to
compile with go 1.20.
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This adds `platform.Readdirnames` which is preparation work before doing
something similar for reading the directory. We use this in gojs as it
doesn't actually need dirents, rather just names.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This centralizes filestat logic by making our own `Stat_t` similar to
`syscall.Stat_t`. This exposes utilities in the platform package and
adds a new function `FS.Stat` which avoids having to use `fs.File` to
get the same info. Doing so at the FS abstraction allows us to optimize
how it is implemented internally using portable means (e.g.
`os.StatFile`) or OS-specific means where necessary, e.g. in windows.
This also ensures `platform.OpenFile` returns syscall.Errno and
centralizes error checking with a new `require.EqualErrno` test.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds `FS.Chmod` and implements it for `GOOS=js`. This function
isn't defined in WASI snapshot01, but it is in `wasi-filesystem`, e.g.
`change-file-permissions-at`.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This implements `fd_datasync` in WASI, falling back to normal
`File.Sync` when unsupported. This also backfills missing usage of sync
in GOOS=js. Finally, this updates the WASI status chart based on what's
implemented.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This moves our floor version to the same we'll release 1.0 with: 1.18.
This is congruent with our version policy which is current-2.
Fixes#921
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This handles edge cases on rename which were previously skipped in
testing. Notably, there are delete flags not possible to propagate in
current versions of go, which imply some copy/paste meanwhile.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Takeshi Yoneda <takeshi@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 implements fd_filestat_set_size and fd_filestat_set_times, which
passes one more test in the rust wasi-testsuite.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Takeshi Yoneda <takeshi@tetrate.io>
This changes the logic inside CompositeFS in preparation of re-using the
user-provided input paths for pre-open paths. The main change here is
retaining original insertion order until runtime, then just iterating
backwards then.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds a new top-level type FSConfig, which is configured via
`ModuleConfig.WithFSConfig(fcfg)`. This implements read-only and
read-write directory mounts, something not formally supported before. It
also implements `WithFS` which adapts a normal `fs.FS`. For convenience,
we retain the old `ModuleConfig.WithFS` signature so as to not affect
existing users much. A new configuration for our emerging raw
filesystem, `FSConfig.WithSysfs()` will happen later without breaking
this API.
Here's an example:
```
moduleConfig = wazero.NewModuleConfig().
// Make the current directory read-only accessible to the guest.
WithReadOnlyDirMount(".", "/")
// Make "/tmp/wasm" accessible to the guest as "/tmp".
WithDirMount("/tmp/wasm", "/tmp")
```
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>