Commit Graph

58 Commits

Author SHA1 Message Date
Pat Hickey
1d663bfd71 delete straggler InDataField 2021-03-24 11:19:12 -07:00
Pat Hickey
e6c7e00a52 wiggle-using crates: delete GuestErrorConversion 2021-03-24 10:39:06 -07:00
Pat Hickey
81dfb9c458 wasi: make WasiSched::sleep fallible
some systems do not support sleeping and may want to return EINVAL here.
2021-03-23 10:20:03 -07:00
Dan Gohman
2880dab8f8 Add a sleep function to the WasiSched trait. 2021-03-22 12:50:16 -07:00
Dan Gohman
6b40724d18 Support "sleep" forms of poll_oneoff.
Add support for `poll_oneoff` calls which just sleep on a relative
timeout. This fixes a bug handling code compiled with WASI libc's `sleep`
family of functions, which call `poll_oneoff` with a `CLOCK_REALTIME`
timer, which wasn't previously implemented.
2021-03-22 12:50:16 -07:00
Christopher Serr
cc84c693a3 wasi-common: Timestamps should be in nanoseconds (#2717)
Sleeping takes 1000x longer than it should because the timestamps are
interpreted as microseconds by accident.
2021-03-10 09:09:34 -06:00
Pat Hickey
bcebdd43ef wiggle use sites: remove ctx argument 2021-03-04 18:16:37 -08:00
Pat Hickey
c9d8ed03c9 wasi-common: fix fdstat of dirfd
the fdstat of a dirfd needs to include both the file and dir rights in
the inheriting field.

The wasi-libc path_open bases the base rights of child directories off
the inheriting rights of the parent, so if we only put file rights in
there, opening a child directory will not have any directory operations
permitted.

Fixes https://github.com/bytecodealliance/wasmtime/issues/2638
2021-02-10 16:53:39 -08:00
Pat Hickey
e2b67aa9a3 simplify life for readdir implementors 2021-02-03 18:04:26 -08:00
Pat Hickey
857ef411b5 upstream fixes are pending for symlink_create & nofollow_errors on windows 2021-02-02 16:23:57 -08:00
Pat Hickey
0ef691b74e rustdocs!! 2021-02-01 18:01:47 -08:00
Pat Hickey
5ee093e774 Merge remote-tracking branch 'origin/main' into pch/wasi_common_cap_std 2021-02-01 13:21:25 -08:00
Peter Huene
4632228b35 Fix fd_readdir to properly truncate directory entry names.
Previously, `fd_readdir` was truncating directory entry names based on the
calculation of `min(name_len, buf_len - bufused)`, but `bufused` was not being
updated after writing in the `dirent` structure to the buffer.

This allowed `bufused` to be incremented beyond `buf_len` and returned as the
number of bytes written to the buffer, which is invalid.

This fix adjusts `bufused` when the buffer is written to for the `dirent` so
that name truncation happens as expected.

Fixes #2618.
2021-02-01 11:41:12 -08:00
Pat Hickey
bad169dde3 port https://github.com/bytecodealliance/wasmtime/pull/2620 into rewrite 2021-02-01 11:10:26 -08:00
Pat Hickey
e940d31f95 add a noent / not_found errorkind 2021-01-30 13:36:41 -08:00
Pat Hickey
3d406ff50e Dir::open_file can just pass read/write as bools, centralizing FileCaps decoding
this way the impls of File/Dir don't need to know about any caps!
2021-01-29 21:04:34 -08:00
Pat Hickey
95ad13c82d wasi-common: break dep on system-interface by defining our own Advice enum 2021-01-29 17:03:08 -08:00
Pat Hickey
d738a4a588 preview 0: copy bodies of read, write, and poll_oneoff from snapshot 1 2021-01-29 12:07:21 -08:00
Pat Hickey
ef2cb7b6b7 nearly have snapshot 0 implemented... 2021-01-28 17:00:31 -08:00
Pat Hickey
47fec44c10 move wasi-c2 into wasi-common 2021-01-28 15:15:50 -08:00
Pat Hickey
dd005208b6 delete wasi-common, yanix, winx 2021-01-28 15:13:45 -08:00
Pat Hickey
b53aecb367 Merge branch 'pch/wiggle_flags_bitflags' into pch/wasi_common_cap_std 2021-01-11 18:31:43 -08:00
Pat Hickey
75a9dc7fe2 wasi-common: wiggle flags are now bitflags!
this mostly mechanical change is just getting rid of passing to
`contains` by reference.
2021-01-11 18:27:55 -08:00
Pat Hickey
13cd7a4a8e Merge branch 'pch/wiggle_trapping' into pch/wasi_common_cap_std 2021-01-07 14:10:59 -08:00
Pat Hickey
b149a03d5d wasi-common: instead of panicking, use an Error::Unsupported that Traps 2021-01-07 14:05:49 -08:00
Pat Hickey
cd3adb1abd Trap::I32Exit is a better name 2021-01-07 11:45:11 -08:00
Pat Hickey
4a574c14eb wasi-common: port to use wiggle::Trap 2021-01-07 11:45:11 -08:00
Pat Hickey
b5852bf5ff open_dir can never create a dir 2020-12-15 16:44:03 -08:00
Dan Gohman
88a073eac3 rustfmt 2020-12-11 10:52:54 -08:00
Dan Gohman
c3f0471ff2 Fix the return value from wasi-common's fd_readdir.
`fd_readdir` returns a "bufused" value, which indicates the number of
bytes read into the buffer. WASI libc expects this value to be equal
to the size of the buffer if the end of the directory has not yet
been scanned.

Previously, wasi-common's `fd_readdir` was writing as many complete
entries as it could fit and then stopping, but this meant it was
returning size less than the buffer size even when the directory had
more entries. This patch makes it continue writing up until the end
of the buffer, and return that number of bytes, to let WASI libc
know that there's more to be read.

Fixes #2493.
2020-12-11 10:52:54 -08:00
Alex Crichton
efe7f37542 Remove duplication in wasi-common for snapshot_0 (#2444)
This commit deletes the old `snapshot_0` implementation of wasi-common,
along with the `wig` crate that was used to generate bindings for it.
This then reimplements `snapshot_0` in terms of
`wasi_snapshot_preview1`. There were very few changes between the two
snapshots:

* The `nlink` field of `FileStat` was increased from 32 to 64 bits.
* The `set` field of `whence` was reordered.
* Clock subscriptions in polling dropped their redundant userdata field.

This makes all of the syscalls relatively straightforward to simply
delegate to the next snapshot's implementation. Some trickery happens to
avoid extra cost when dealing with iovecs, but since the memory layout
of iovecs remained the same this should still work.

Now that `snapshot_0` is using wiggle we simply have a trait to
implement, and that's implemented for the same `WasiCtx` that has the
`wasi_snapshot_preview1` trait implemented for it as well. While this
theoretically means that you could share the file descriptor table
between the two snapshots that's not supported in the generated bindings
just yet. A separate `WasiCtx` will be created for each WASI module.
2020-11-30 12:27:49 -06:00
Pat Hickey
26192d6760 wasi-common: opt in to mutable borrowing 2020-11-18 14:43:47 -08:00
Pat Hickey
6db24fd08f handle: re-export all of the wasi types used by handles 2020-09-14 16:42:20 -07:00
Pat Hickey
39f1c9716c restructure StringArrayWriter trait into StringArray struct 2020-09-02 14:11:32 -07:00
Pat Hickey
51d88f7899 wasi-common: move implementation of args, env methods into StringArrayWriter 2020-09-01 13:50:31 -07:00
Pat Hickey
87222d6db0 wasi-common: move GuestPtr deref out of path::get 2020-09-01 13:50:30 -07:00
Pat Hickey
393581b2ae Merge branch 'main' into pch/wasi_error_handling 2020-08-26 17:26:03 -07:00
Pat Hickey
7e750845cd Remove unnecessary check - fixed in std since Rust 1.38
issue now closed: https://github.com/rust-lang/rust/issues/63326
fix landed in a rollup: https://github.com/rust-lang/rust/pull/63380 merged aug 8, 2019
rust 1.38 beta cut on aug 15, 2019: https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html
minimum supported rust version for this repo is currently 1.41.
2020-08-25 17:27:47 -07:00
Pat Hickey
02aba548e1 Merge remote-tracking branch 'origin/main' into pch/wasi_error_handling 2020-08-25 15:22:51 -07:00
Pat Hickey
e8c01ddef1 put getrandom::Error into Error 2020-08-19 14:29:14 -07:00
Pat Hickey
e8160c9a6b redefine crate to use Error everywhere except in wasi 2020-08-18 10:50:17 -07:00
Pat Hickey
94ee96712a wasi-common: switch all logs from log to tracing
tracing is already the dep that wiggle uses.

I used tracing structured arguments wherever I could, but I skipped over
it in all of the snapshot_0 code, because I'm going to delete that code
and replace it with wiggle-based stuff real soon.
2020-08-18 10:46:14 -07:00
Jakub Konka
60d55a3483 Remove a runaway explicit drop 2020-06-13 15:55:01 +02:00
Pat Hickey
b130a64d19 wasi-common fixes 2020-05-20 12:51:28 -07:00
Pat Hickey
04fb4acc6a wasi-common: WIP translating to use automated borrow checking 2020-05-20 12:51:28 -07:00
Jakub Konka
348be6f3ed Revert fstatat on *nix and test symlinks in path_filestat calls (#1725)
* Revert fstatat on *nix and test symlinks in path_filestat calls

This commit effectively reverts too eager refactoring on my part which
resulted in incorrect `path_filestat_{get, set_times}` behaviour on
*nix hosts. In the presence of symlinks, neither of the calls would
work properly.

In order to shield ourselves from similar errors in the future, I've
augmented the `path_filestat` test cases with symlink checks as well.

* Pass appropriate flags to fstatat and utimensat

* Fix formatting

* Fix Windows build

* Expand final symlinks if follow is set on Windows

* Fix formatting

* Do not follow symlinks unless specified on Windows

* Update comments and restart CI

* Skip testing volatile atim field
2020-05-20 12:02:24 -07:00
Dan Gohman
fb0b9e3ae6 Change proc_exit to unwind the stack rather than exiting the host process. (#1646)
* Remove Cranelift's OutOfBounds trap, which is no longer used.

* Change proc_exit to unwind instead of exit the host process.

This implements the semantics in https://github.com/WebAssembly/WASI/pull/235.

Fixes #783.
Fixes #993.

* Fix exit-status tests on Windows.

* Revert the wiggle changes and re-introduce the wasi-common implementations.

* Move `wasi_proc_exit` into the wasmtime-wasi crate.

* Revert the spec_testsuite change.

* Remove the old proc_exit implementations.

* Make `TrapReason` an implementation detail.

* Allow exit status 2 on Windows too.

* Fix a documentation link.

* Really fix a documentation link.
2020-05-13 15:59:43 -07:00
Jakub Konka
cbf7cbfa39 Introduce strongly-typed system primitives (#1561)
* Introduce strongly-typed system primitives

This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are: `OsFile`, `OsDir`, `Stdio`,
and `OsOther`. Those primitives are separate structs now, each implementing
a subset of `Handle` methods, rather than all being an enumeration of some
supertype such as `OsHandle`. To summarise the structs:

* `OsFile` represents a regular file, and implements fd-ops
  of `Handle` trait
* `OsDir` represents a directory, and primarily implements path-ops, plus
  `readdir` and some common fd-ops such as `fdstat`, etc.
* `Stdio` represents a stdio handle, and implements a subset of fd-ops
  such as `fdstat` _and_ `read_` and `write_vectored` calls
* `OsOther` currently represents anything else and implements a set similar
  to that implemented by `Stdio`

This commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.

Some more minor changes include making `OsHandle` represent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, since `OsDir`
is tricky across OSes, we also have a supertype of `OsHandle` called
`OsDirHandle` which may store a `DIR*` stream pointer (mainly BSD). Last but not
least, the `Filetype` and `Rights` are now computed when the resource is created,
rather than every time we call `Handle::get_file_type` and `Handle::get_rights`.
Finally, in order to facilitate the latter, I've converted `EntryRights` into
`HandleRights` and pushed them into each `Handle` implementor.

* Do not adjust rights on Stdio

* Clean up testing for TTY and escaping writes

* Implement AsFile for dyn Handle

This cleans up a lot of repeating boilerplate code todo with
dynamic dispatch.

* Delegate definition of OsDir to OS-specific modules

Delegates defining `OsDir` struct to OS-specific modules (BSD, Linux,
Emscripten, Windows). This way, `OsDir` can safely re-use `OsHandle`
for raw OS handle storage, and can store some aux data such as an
initialized stream ptr in case of BSD. As a result, we can safely
get rid of `OsDirHandle` which IMHO was causing unnecessary noise and
overcomplicating the design. On the other hand, delegating definition
of `OsDir` to OS-specific modules isn't super clean in and of itself
either. Perhaps there's a better way of handling this?

* Check if filetype of OS handle matches WASI filetype when creating

It seems prudent to check if the passed in `File` instance is of
type matching that of the requested WASI filetype. In other words,
we'd like to avoid situations where `OsFile` is created from a
pipe.

* Make AsFile fallible

Return `EBADF` in `AsFile` in case a `Handle` cannot be made into
a `std::fs::File`.

* Remove unnecessary as_file conversion

* Remove unnecessary check for TTY for Stdio handle type

* Fix incorrect stdio ctors on Unix

* Split Stdio into three separate types: Stdin, Stdout, Stderr

* Rename PendingEntry::File to PendingEntry::OsHandle to avoid confusion

* Rename OsHandle to RawOsHandle

Also, since `RawOsHandle` on *nix doesn't need interior mutability
wrt the inner raw file descriptor, we can safely swap the `RawFd`
for `File` instance.

* Add docs explaining what OsOther is

* Allow for stdio to be non-character-device (e.g., piped)

* Return error on bad preopen rather than panic
2020-05-07 16:00:14 -07:00
Jakub Konka
de919382b3 Make Handle a trait required for any WASI-compatible handle (#1443)
* Make Handle a trait required for any WASI-compatible handle

OK, so this PR is a bit of an experiment that came about somewhat itself
when I was looking at refactoring use of `Rc<RefCell<Descriptor>>` inside
`Entry` struct. I've noticed that since we've placed `VirtualFile` on the
same level as `OsHandle` and `Stdin` etc., we've ended up necessiitating
checks for different combinations such as "is a real OS resource being mixed
up with a virtual resource?", and if that was the case, we'd panic since
this was clearly not allowed (e.g., symlinking, or worse renaming).
Therefore, it seemed natural for virtual file to be on the same level
as _any_ OS handle (regardless of whether it's an actual file, socket,
or stdio handle). In other words, we should ideally envision the following
hierarchy:

```
\-- OsHandle \-- OsFile
              -- Stdio
\-- Virtual
```

This way, we can deal with the mix up at a level above which cleans up
our logic significantly.

On the other hand, when looking through the `virtfs`, the trait approach
to some type that's a valid `Handle` grew on me, and I think this
is the way to go. And this is what this PR is proposing, a trait
`Handle` which features enough functionality to make both virtual and
OS ops to work. Now, inside `Entry` we can safely store something like
`Rc<dyn Handle>` where `Handle` can downcast to either `VirtualFile` or
`VirtualDir`, or `OsHandle` if its an actual OS resource. Note that
I've left `Handle` as one massive trait, but I reckon we could split
it up into several smaller traits, each dealing with some bit of WASI
functionality. I'm hoping this would perhaps make it easier to figure
out polyfilling between snapshots and the new upcoming ephemeral
snapshot since a lot of boilerplate functionality is now done as part
of the `Handle` trait implementation.

Next, I've redone the original `OsHandle` to be an `OsFile` which
now stores a raw descriptor/handle (`RawFd`/`RawHandle`) inside a
`Cell` so that we can handle interior mutability in an easy (read,
non-panicky) way. In order not to lose the perks of derefercing to
`std::fs::File`, I've added a convenience trait `AsFile` which
will take `OsFile` by reference (or the stdio handles) and create
a non-owned `ManuallyDrop<File>` resource which can be passed around
and acted upon the way we'd normally do on `&File`. This change of
course implies that we now have to worry about properly closing all
OS resources stored as part of `OsFile`, thus this type now implements
`Drop` trait which essentially speaking moves the raw descriptor/handle
into a `File` and drops it.

Finally, I've redone setting time info on relative paths on *nix using
the same approach as advocated in the virtual fs. Namely, we do an
`openat` followed by `filestat_set_times` on the obtained descriptor.
This effectively removes the need for custom `filetime` module in
`yanix`. However, this does probably incur additional cost of at least
one additional syscall, and I haven't checked whether this approach
performs as expected on platforms such as NixOS which as far as I remember
had some weirdness todo with linking `utimensat` symbols, etc. Still,
this change is worth considering given that the implementation of
`path_filestat_set_times` cleans up a lot, albeit with some additional
cost.

* Fix tests on Windows

* Address comments plus minor consistency cleanup

* Address comments

* Fix formatting
2020-04-09 22:18:19 +02:00
Jakub Konka
78772cf5e1 Generate trace logs in wiggle albeit behind a feature gate
This commit augments `wiggle` with trace log generation for the shims,
returned errno values, and returned values proper (if any, i.e.,
different than unit type `()`). What that means is that every syscall
will have auto-generated up to 3 traces, for instance,

```
 TRACE wasi_common::wasi::wasi_snapshot_preview1 > fd_prestat_get(fd=Fd(3))
 TRACE wasi_common::wasi::wasi_snapshot_preview1 >      | result=(buf=Dir(PrestatDir { pr_name_len: 1 }))
 TRACE wasi_common::wasi::wasi_snapshot_preview1 >      | errno=No error occurred. System call completed successfully. (Errno::Success(0))
```

Putting logging behind a feature gate in this case means that the log calls
are generated by the `wiggle` crate regardless if the client requested
the feature or not, however, then their usage in the client lib is
dictated by the presence of the feature flag. So, for instance, `wasi-common`
has this feature enabled by default, while any other client lib
using `wiggle` if they don't want tracing enabled, they will just
leave the feature off. I'm not sure if this is what we wanted
but seemed easiest to implement quickly. Lemme y'all know your thoughts
about this!
2020-03-30 19:58:15 +02:00