Bug 1967206 - Update jobserver (and related crates to avoid duplication). r=glandium,supply-chain-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D250045
This commit is contained in:
Emilio Cobos Álvarez
2025-05-20 22:50:16 +00:00
committed by ealvarez@mozilla.com
parent 918aea565d
commit caf0070ab3
113 changed files with 10826 additions and 7334 deletions

37
Cargo.lock generated
View File

@@ -2482,21 +2482,21 @@ dependencies = [
name = "getrandom" name = "getrandom"
version = "0.2.999" version = "0.2.999"
dependencies = [ dependencies = [
"getrandom 0.3.1", "getrandom 0.3.3",
] ]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.3.1" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"js-sys", "js-sys",
"libc", "libc",
"wasi 0.13.0+wasi-0.2.0", "r-efi",
"wasi 0.14.2+wasi-0.2.4",
"wasm-bindgen", "wasm-bindgen",
"windows-targets",
] ]
[[package]] [[package]]
@@ -3503,10 +3503,11 @@ dependencies = [
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.32" version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
dependencies = [ dependencies = [
"getrandom 0.3.3",
"libc", "libc",
] ]
@@ -5489,6 +5490,10 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "r-efi"
version = "5.999.999"
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.5" version = "0.8.5"
@@ -6567,7 +6572,7 @@ checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"getrandom 0.3.1", "getrandom 0.3.3",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys", "windows-sys",
@@ -7356,23 +7361,22 @@ dependencies = [
name = "wasi" name = "wasi"
version = "0.10.0+wasi-snapshot-preview999" version = "0.10.0+wasi-snapshot-preview999"
dependencies = [ dependencies = [
"wasi 0.13.0+wasi-0.2.0", "wasi 0.14.2+wasi-0.2.4",
] ]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.999" version = "0.11.999"
dependencies = [ dependencies = [
"wasi 0.13.0+wasi-0.2.0", "wasi 0.14.2+wasi-0.2.4",
] ]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.13.0+wasi-0.2.0" version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "652cd73449d0b957a2743b70c72d79d34a5fa505696488f4ca90b46f6da94118" checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [ dependencies = [
"bitflags 2.9.0",
"wit-bindgen-rt", "wit-bindgen-rt",
] ]
@@ -7865,9 +7869,12 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rt" name = "wit-bindgen-rt"
version = "0.21.0" version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "026d24a27f6712541fa534f2954bd9e0eb66172f033c2157c0f31d106255c497" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.0",
]
[[package]] [[package]]
name = "wpf-gpu-raster" name = "wpf-gpu-raster"

View File

@@ -131,6 +131,9 @@ terminal_size = { path = "build/rust/terminal_size" }
# Patch bitflags 1.0 to 2.0 # Patch bitflags 1.0 to 2.0
bitflags = { path = "build/rust/bitflags" } bitflags = { path = "build/rust/bitflags" }
# Patch r-efi to an empty crate
r-efi = { path = "build/rust/r-efi" }
# Patch redox_users to an empty crate # Patch redox_users to an empty crate
redox_users = { path = "build/rust/redox_users" } redox_users = { path = "build/rust/redox_users" }
@@ -146,10 +149,10 @@ base64_13 = { package = "base64", path = "build/rust/base64_13" }
# Patch base64 0.21 to 0.22 # Patch base64 0.21 to 0.22
base64_21 = { package = "base64", path = "build/rust/base64" } base64_21 = { package = "base64", path = "build/rust/base64" }
# Patch wasi 0.10 to 0.13 # Patch wasi 0.10 to 0.14
wasi_0_10 = { package = "wasi", path = "build/rust/wasi-0.10" } wasi_0_10 = { package = "wasi", path = "build/rust/wasi-0.10" }
# Patch wasi 0.11 to 0.13 # Patch wasi 0.11 to 0.14
wasi_0_11 = { package = "wasi", path = "build/rust/wasi" } wasi_0_11 = { package = "wasi", path = "build/rust/wasi" }
# tokio 0.29.0 includes an experimental "tracing" feature which requires # tokio 0.29.0 includes an experimental "tracing" feature which requires

View File

@@ -0,0 +1,8 @@
[package]
name = "r-efi"
version = "5.999.999"
edition = "2018"
license = "MPL-2.0"
[lib]
path = "lib.rs"

3
build/rust/r-efi/lib.rs Normal file
View File

@@ -0,0 +1,3 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

View File

@@ -8,7 +8,7 @@ license = "MPL-2.0"
path = "lib.rs" path = "lib.rs"
[dependencies.wasi] [dependencies.wasi]
version = "0.13.0" version = "0.14.0"
default-features = false default-features = false
[features] [features]

View File

@@ -8,7 +8,7 @@ license = "MPL-2.0"
path = "lib.rs" path = "lib.rs"
[dependencies.wasi] [dependencies.wasi]
version = "0.13.0" version = "0.14.0"
default-features = false default-features = false
[features] [features]

View File

@@ -2563,6 +2563,19 @@ In addition, I've checked Linux, Windows, Mac, and Android more thoroughly again
documentation. documentation.
""" """
[[audits.getrandom]]
who = "Emilio Cobos Álvarez <emilio@crisal.io>"
criteria = "safe-to-deploy"
delta = "0.3.1 -> 0.3.3"
notes = """
Biggest non-trivial change is a new UEFI back-end, which looks reasonable to
the best of my ability: There's some trickiness on initialization but doesn't
look unsafe, at worse it leaks, and it might not if the relevant pointers are
static/non-owning. Other changes also look reasonable too: some tweaks to
inlining and a syscall-based linux back-end, whose relevant unsafe code looks
reasonable.
"""
[[audits.gimli]] [[audits.gimli]]
who = "Alex Franchuk <afranchuk@mozilla.com>" who = "Alex Franchuk <afranchuk@mozilla.com>"
criteria = "safe-to-deploy" criteria = "safe-to-deploy"
@@ -3130,6 +3143,12 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy" criteria = "safe-to-deploy"
delta = "0.1.24 -> 0.1.25" delta = "0.1.24 -> 0.1.25"
[[audits.jobserver]]
who = "Emilio Cobos Álvarez <emilio@crisal.io>"
criteria = "safe-to-deploy"
delta = "0.1.32 -> 0.1.33"
notes = "No unsafe added, only non-trivial change is switching to the getrandom crate on Windows."
[[audits.keccak]] [[audits.keccak]]
who = "Simon Friedberger <simon@mozilla.com>" who = "Simon Friedberger <simon@mozilla.com>"
criteria = "safe-to-deploy" criteria = "safe-to-deploy"
@@ -6951,7 +6970,7 @@ end = "2024-05-08"
criteria = "safe-to-deploy" criteria = "safe-to-deploy"
user-id = 1 # Alex Crichton (alexcrichton) user-id = 1 # Alex Crichton (alexcrichton)
start = "2020-06-03" start = "2020-06-03"
end = "2024-05-05" end = "2026-05-19"
[[trusted.wasm-encoder]] [[trusted.wasm-encoder]]
criteria = "safe-to-deploy" criteria = "safe-to-deploy"

View File

@@ -785,8 +785,8 @@ user-login = "seanmonstar"
user-name = "Sean McArthur" user-name = "Sean McArthur"
[[publisher.wasi]] [[publisher.wasi]]
version = "0.13.0+wasi-0.2.0" version = "0.14.2+wasi-0.2.4"
when = "2024-03-12" when = "2025-02-28"
user-id = 1 user-id = 1
user-login = "alexcrichton" user-login = "alexcrichton"
user-name = "Alex Crichton" user-name = "Alex Crichton"
@@ -885,8 +885,8 @@ user-login = "epage"
user-name = "Ed Page" user-name = "Ed Page"
[[publisher.wit-bindgen-rt]] [[publisher.wit-bindgen-rt]]
version = "0.21.0" version = "0.39.0"
when = "2024-03-04" when = "2025-02-05"
user-id = 73222 user-id = 73222
user-login = "wasmtime-publish" user-login = "wasmtime-publish"

View File

@@ -1 +1 @@
{"files":{"CHANGELOG.md":"3000732ebdbde090f0f971e87b1bffa89de25ae70fc282b58c6c4ed7f574eea7","Cargo.toml":"448e4ae3f4a71ebd55435f6de05ef03cb4ad8ad27cc586305c39f58491f075b8","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"42fa16951ce7f24b5a467a40e5b449a1d41e662f97ca779864f053f39e097737","README.md":"89acb2c8a9b37d50ee569ac163e3eac9d3c1b003631bd95bd3397daa34d4e2bf","SECURITY.md":"816ea79f8c7937888ab5a972a1efb270c4bada028b448953a195359fe11d526e","benches/buffer.rs":"20fb7dd9edafe0c182f1fe037b28d7542f8e0ae742d51e97aeebf418edde49aa","build.rs":"5b6a7fe4b07f17eab0cef06d80721ffbfa22527577b0d13bdb71306ae45cd96c","src/backends.rs":"00cdd73cc21c4e76ebd60cae2199c1b7de6fd24ca7a59d868a7c999244959c2e","src/backends/apple_other.rs":"7e1f893a6eb3da9238a5510d5b6d5c3db7c6aee77becd64b6707778ec4915cff","src/backends/custom.rs":"c921b05cbeb7f22bfe59d65cf9fd2f232874cfd7bb019ede80a2f7e97cfd63c8","src/backends/esp_idf.rs":"dc16e3669e4bb13cc0e9b8c4d6888a991de3c501a4527b649804450adb11a93d","src/backends/fuchsia.rs":"8b367069acf80094e3fb1a3044a6141e9ed5267667c0a2ed91ee83f0b620506b","src/backends/getentropy.rs":"035ec45cfed3efa4fcd3d5ff3453430c87e02d106578a22ba7e52c11d7494cdf","src/backends/getrandom.rs":"6bfeca07027237cc44b4591740f69813ab3f2f4bcd047b7fe495b94af11881ea","src/backends/hermit.rs":"9500f549c9a167b62169fb163617007f20f7adce0990f54d8a990b449504c8b7","src/backends/linux_android.rs":"78b2f2734422154b62541d3bb728d32bb09d30a704e69ca6a9b6faca44da2caa","src/backends/linux_android_with_fallback.rs":"a266494b23e194629893a1082ab7e942118d89d15311f1f6f519fbc4495687e9","src/backends/netbsd.rs":"5f3cf054961b3732aa177d0f354e4ee0fba31ac5384ac9245e15801237223db8","src/backends/rdrand.rs":"995f4532722aa90ea9228daa167ed63520715041ff6d73368bf2eb394dbe5c24","src/backends/rndr.rs":"4e1ce1e28dda72c8a3a29bfa62240f9d0fdb89ee1f7af2fb38dc570e79e2cbc1","src/backends/solaris.rs":"f9972e8748260567c90f209913045df312bfe39f6999e3b21617cb16446aedba","src/backends/solid.rs":"1d99a7299e309d5f0cc66efa68b31daa436a1dbf2fb8e1f9c1e99ca45c2943ca","src/backends/use_file.rs":"b835a4517e8c7f3bfa879b2395b65baafe69ee41d0bd922a2ffa9186f5feedfe","src/backends/vxworks.rs":"be8c29e6bb3cc8c60aaccd12a68e28612ee308e3023f9ede700433c0ecbf1d63","src/backends/wasi_p1.rs":"16771c1089a2b81f48e04f0e78e598106d525d0d5c1d4152230a1ef1c84c2b4f","src/backends/wasi_p2.rs":"84a69c83df27c2d028c975d89e27f402c1ef24e2c972f5f71fef947dc90f0cf2","src/backends/wasm_js.rs":"42dbddf2648f4b358d5246e294ec1a2c48ec245b2be00452772b26c5fb37cd82","src/backends/windows.rs":"6f2d2090980d53d5bca41bd5638af0106f9c804e9e696a545430862fdc631e63","src/backends/windows7.rs":"8c25d1d7d97b64a45186644bd8c41e9eb1b99ce622221f4cdfaa7d584afc1fcc","src/error.rs":"9c0db953fc3b54c7535e76068362168203e777d0d7ba81025744ae58702a78e1","src/error_std_impls.rs":"4c068e81d876237a7e0a0e91519896bd670c2f999ca729f7fb970caf888cab46","src/lazy.rs":"9c7e3efcc7b4cc2252751d29e42465bae8cbe49461a4a81a006d8d2c45003fd1","src/lib.rs":"4342b61e1564ea792791bcbc8bcd2403633016473e6c74e5f8bc92866e340cc8","src/util.rs":"1c5000cac8e43ddbc31a2f1b900c9ace6e3ccf32f362fa13fdee09d2c219136c","src/util_libc.rs":"0a6a6fcc5b32b78f02828fd2e76ff0642966935108dc90159ba40bdb9c1cf1ba","tests/mod.rs":"b8e88300a1ec0b2f6cbc03d40cc66eacae625d1fdc1163f4cf50fae7712d2bdc"},"package":"43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"} {"files":{"CHANGELOG.md":"fc99d55b89ff2dcca19d1d36f4e10b76e5adecc211afff67aac4d199f35e435c","Cargo.lock":"e55b09b283d1685505f5d15a2d79f0a7c1de35c79321eafd02074c815ef67597","Cargo.toml":"c11a6fef961eec45202c915ccde2aeec475c0950f31cb3c5a74e65fea2262bbc","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"29e9fe5074bd27e0e5d5d110394fbbcd841baee2651a3c4b4560a632702cede4","README.md":"5afb17166a328f69726ae52321b3c6f698adefbfc64898e93e45cd3d4ce3e1e5","SECURITY.md":"816ea79f8c7937888ab5a972a1efb270c4bada028b448953a195359fe11d526e","benches/buffer.rs":"20fb7dd9edafe0c182f1fe037b28d7542f8e0ae742d51e97aeebf418edde49aa","build.rs":"9280e324b69c0c80c65de8074046104ac561cbfe0b7856e02a939e491936aaac","src/backends.rs":"1c43868fdb6b1bfd0f6b6ac1e4f8195ad0045fa472e366821be2249ef5aa6da6","src/backends/apple_other.rs":"f8fa784588f347cfd7c2b5f37a96b23d446f95c3157668069d7146e281fa783b","src/backends/custom.rs":"c8776ff0dda65cef1373b8624043f8a42ce4fd6183fbeb8918f9df5d4a13d457","src/backends/efi_rng.rs":"873b7343a003a5f222753fbd50cba3f2beeacec4386ad3272ec98d654a4466d4","src/backends/esp_idf.rs":"b50d6c582b49488204151c2036a100aac7902b8215fb791f271e1b5fc772db9a","src/backends/fuchsia.rs":"d7c660a62f1da2c41c537ccea085bba6d3f83b82c34e6e63175130feca9dece8","src/backends/getentropy.rs":"a0fdf57546e20be8e76d21ec5f815f07a3a4dfb590d4d693cc2e78b494676304","src/backends/getrandom.rs":"1d165160ab4526534f0981d0cddee4075d6ddfc07d7a3086b0b30544ad755b17","src/backends/hermit.rs":"92e0cf4103b5ddc15ed48cad8d7165ba8e344fde0f07960385b36590466ee67c","src/backends/linux_android_with_fallback.rs":"ba4b820542aceee7b3b0b8b8be6460140cd0f601132b4e79f1abe0051a997af8","src/backends/linux_raw.rs":"eea0428ac3a803ae1c8463cdbaf385b73008ec67a02c7c634eb4ce01589a97f8","src/backends/netbsd.rs":"ca6a6c4c17c04ec987002296debdd7a03b10f5efd5bcb79f159b9a13c4b6821f","src/backends/rdrand.rs":"2a06eb62ad7e97c2486ab1b0159e4b9fe3a1c0a39d479a836d23051f89cb9aed","src/backends/rndr.rs":"bc06a88e3314a06494b6fe70bdae684fe45f9a6a63d28c61dbd90f66595424d0","src/backends/solaris.rs":"b263a3e8bc3c490a0c589d2a1a67d8fdb36119993df1f8d05f43975ff88f9c3e","src/backends/solid.rs":"1c92fc4c5a8ac67b64af560bb7843d6e447efe9785e557f064348fb84b83ceb8","src/backends/use_file.rs":"a2582912793ed985f7c092243405c8ee15fc2d6cb23ef4233a842325cec69492","src/backends/vxworks.rs":"64ee8619c5b5aa267761aabc99552ba8df71d14cda7cc66d6c1e4f4fb1ed8d00","src/backends/wasi_p1.rs":"77755c8fefb9f36509b2e6764edb9f8293dc1efa3d5a9bc85d28723ceeb7aec0","src/backends/wasi_p2.rs":"5821dff8eb2a145a49adcb751f9ec794e0fb8989ff625c70a98afcba48de0731","src/backends/wasm_js.rs":"5913b33ec9cb4076cef65d461ce82af98e9233f621eac8fab44b68fd37080927","src/backends/windows.rs":"60a5c9a87c8b35d3816c8909d051ce76741121806de6ea4f17a847c89b9cd4a2","src/backends/windows7.rs":"a5fac48672fa109eff2dc67f424fe99fabe4ec8af4802ce4ecc2f07706b2201c","src/error.rs":"6497fc88435c341e5547c35f259f9bebf1272b83b782794d8c6251a4c3159d28","src/error_std_impls.rs":"4c068e81d876237a7e0a0e91519896bd670c2f999ca729f7fb970caf888cab46","src/lazy.rs":"9c7e3efcc7b4cc2252751d29e42465bae8cbe49461a4a81a006d8d2c45003fd1","src/lib.rs":"54279c7e2ac54bf990c89c37f12754da7183cde6fb51d9e6900aaaed4e1f995f","src/util.rs":"207e21353f4e402daf84ff137c8d4aa4ffafa48141194ae7148252e06dcadd9f","src/util_libc.rs":"1d3f16d8996295822e6cbfc848e90912795f378913627c6b765f47b2185d9480","tests/mod.rs":"b8e88300a1ec0b2f6cbc03d40cc66eacae625d1fdc1163f4cf50fae7712d2bdc"},"package":"26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"}

View File

@@ -4,6 +4,61 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.3.3] - 2025-05-09
### Changed
- Doc improvements [#632] [#634] [#635]
- Add crate version to docs.rs links used in `compile_error!`s [#639]
## Fixed
- Error handling in WASI p1 [#661]
[#632]: https://github.com/rust-random/getrandom/pull/632
[#634]: https://github.com/rust-random/getrandom/pull/634
[#635]: https://github.com/rust-random/getrandom/pull/635
[#639]: https://github.com/rust-random/getrandom/pull/639
[#661]: https://github.com/rust-random/getrandom/pull/661
## [0.3.2] - 2025-03-17
### Added
- `efi_rng` opt-in backend [#570]
- `linux_raw` opt-in backend [#572]
- `.cargo/config.toml` example in the crate-level docs [#591]
- `getrandom_test_linux_without_fallback` configuration flag to test that file fallback
is not triggered in the `linux_android_with_fallback` backend [#605]
- Built-in support for `*-linux-none` targets [#618]
- Cygwin support [#626]
### Changed
- Update `wasi` dependency to v0.14 [#594]
- Add `#[inline]` attribute to the inner functions [#596]
- Update WASI and Emscripten links in the crate-level docs [#597]
- Do not use `dlsym` on MUSL targets in the `linux_android_with_fallback` backend [#602]
- Remove `linux_android.rs` and use `getrandom.rs` instead [#603]
- Always use `RtlGenRandom` on Windows targets when compiling with pre-1.78 Rust [#610]
- Internal representation of the `Error` type [#614]
- Remove `windows-targets` dependency and use [`raw-dylib`] directly [#627]
### Removed
- `Error::INTERNAL_START` and `Error::CUSTOM_START` associated constants [#614]
[#570]: https://github.com/rust-random/getrandom/pull/570
[#572]: https://github.com/rust-random/getrandom/pull/572
[#591]: https://github.com/rust-random/getrandom/pull/591
[#594]: https://github.com/rust-random/getrandom/pull/594
[#596]: https://github.com/rust-random/getrandom/pull/596
[#597]: https://github.com/rust-random/getrandom/pull/597
[#602]: https://github.com/rust-random/getrandom/pull/602
[#603]: https://github.com/rust-random/getrandom/pull/603
[#605]: https://github.com/rust-random/getrandom/pull/605
[#610]: https://github.com/rust-random/getrandom/pull/610
[#614]: https://github.com/rust-random/getrandom/pull/614
[#618]: https://github.com/rust-random/getrandom/pull/618
[#626]: https://github.com/rust-random/getrandom/pull/626
[#627]: https://github.com/rust-random/getrandom/pull/627
[`raw-dylib`]: https://doc.rust-lang.org/reference/items/external-blocks.html?highlight=link#dylib-versus-raw-dylib
## [0.3.1] - 2025-01-28 ## [0.3.1] - 2025-01-28
### Fixed ### Fixed
@@ -76,6 +131,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#571]: https://github.com/rust-random/getrandom/pull/571 [#571]: https://github.com/rust-random/getrandom/pull/571
[#574]: https://github.com/rust-random/getrandom/pull/574 [#574]: https://github.com/rust-random/getrandom/pull/574
## [0.2.16] - 2025-04-22
### Added
- Cygwin support (backport of [#626]) [#654]
[#654]: https://github.com/rust-random/getrandom/pull/654
## [0.2.15] - 2024-05-06 ## [0.2.15] - 2024-05-06
### Added ### Added
- Apple visionOS support [#410] - Apple visionOS support [#410]
@@ -526,7 +587,11 @@ Publish initial implementation.
## [0.0.0] - 2019-01-19 ## [0.0.0] - 2019-01-19
Publish an empty template library. Publish an empty template library.
[0.3.3]: https://github.com/rust-random/getrandom/compare/v0.3.2...v0.3.3
[0.3.2]: https://github.com/rust-random/getrandom/compare/v0.3.1...v0.3.2
[0.3.1]: https://github.com/rust-random/getrandom/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/rust-random/getrandom/compare/v0.2.15...v0.3.0 [0.3.0]: https://github.com/rust-random/getrandom/compare/v0.2.15...v0.3.0
[0.2.16]: https://github.com/rust-random/getrandom/compare/v0.2.15...v0.2.16
[0.2.15]: https://github.com/rust-random/getrandom/compare/v0.2.14...v0.2.15 [0.2.15]: https://github.com/rust-random/getrandom/compare/v0.2.14...v0.2.15
[0.2.14]: https://github.com/rust-random/getrandom/compare/v0.2.13...v0.2.14 [0.2.14]: https://github.com/rust-random/getrandom/compare/v0.2.13...v0.2.14
[0.2.13]: https://github.com/rust-random/getrandom/compare/v0.2.12...v0.2.13 [0.2.13]: https://github.com/rust-random/getrandom/compare/v0.2.12...v0.2.13
@@ -542,7 +607,7 @@ Publish an empty template library.
[0.2.3]: https://github.com/rust-random/getrandom/compare/v0.2.2...v0.2.3 [0.2.3]: https://github.com/rust-random/getrandom/compare/v0.2.2...v0.2.3
[0.2.2]: https://github.com/rust-random/getrandom/compare/v0.2.1...v0.2.2 [0.2.2]: https://github.com/rust-random/getrandom/compare/v0.2.1...v0.2.2
[0.2.1]: https://github.com/rust-random/getrandom/compare/v0.2.0...v0.2.1 [0.2.1]: https://github.com/rust-random/getrandom/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/rust-random/getrandom/compare/v0.1.15...v0.2.0 [0.2.0]: https://github.com/rust-random/getrandom/compare/v0.1.16...v0.2.0
[0.1.16]: https://github.com/rust-random/getrandom/compare/v0.1.15...v0.1.16 [0.1.16]: https://github.com/rust-random/getrandom/compare/v0.1.15...v0.1.16
[0.1.15]: https://github.com/rust-random/getrandom/compare/v0.1.14...v0.1.15 [0.1.15]: https://github.com/rust-random/getrandom/compare/v0.1.14...v0.1.15
[0.1.14]: https://github.com/rust-random/getrandom/compare/v0.1.13...v0.1.14 [0.1.14]: https://github.com/rust-random/getrandom/compare/v0.1.13...v0.1.14

365
third_party/rust/getrandom/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,365 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "bumpalo"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "cc"
version = "1.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "compiler_builtins"
version = "0.1.157"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74f103f5a97b25e3ed7134dee586e90bbb0496b33ba41816f0e7274e5bb73b50"
[[package]]
name = "getrandom"
version = "0.3.3"
dependencies = [
"cfg-if",
"compiler_builtins",
"js-sys",
"libc",
"r-efi",
"rustc-std-workspace-core",
"wasi",
"wasm-bindgen",
"wasm-bindgen-test",
]
[[package]]
name = "js-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "minicov"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b"
dependencies = [
"cc",
"walkdir",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "rustc-std-workspace-core"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9c45b374136f52f2d6311062c7146bff20fec063c3f5d46a410bd937746955"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
dependencies = [
"cfg-if",
"js-sys",
"once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "wasm-bindgen-test"
version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3"
dependencies = [
"js-sys",
"minicov",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-bindgen-test-macro",
]
[[package]]
name = "wasm-bindgen-test-macro"
version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "web-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]

View File

@@ -13,7 +13,7 @@
edition = "2021" edition = "2021"
rust-version = "1.63" rust-version = "1.63"
name = "getrandom" name = "getrandom"
version = "0.3.1" version = "0.3.3"
authors = ["The Rand Project Developers"] authors = ["The Rand Project Developers"]
build = "build.rs" build = "build.rs"
exclude = [".*"] exclude = [".*"]
@@ -45,6 +45,17 @@ pre-build = [
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = ["std"] features = ["std"]
[features]
rustc-dep-of-std = [
"dep:compiler_builtins",
"dep:core",
]
std = []
wasm_js = [
"dep:wasm-bindgen",
"dep:js-sys",
]
[lib] [lib]
name = "getrandom" name = "getrandom"
path = "src/lib.rs" path = "src/lib.rs"
@@ -69,18 +80,7 @@ version = "1.0"
optional = true optional = true
package = "rustc-std-workspace-core" package = "rustc-std-workspace-core"
[features] [target.'cfg(all(any(target_os = "linux", target_os = "android"), not(any(all(target_os = "linux", target_env = ""), getrandom_backend = "custom", getrandom_backend = "linux_raw", getrandom_backend = "rdrand", getrandom_backend = "rndr"))))'.dependencies.libc]
rustc-dep-of-std = [
"dep:compiler_builtins",
"dep:core",
]
std = []
wasm_js = [
"dep:wasm-bindgen",
"dep:js-sys",
]
[target.'cfg(all(any(target_os = "linux", target_os = "android"), not(any(getrandom_backend = "custom", getrandom_backend = "rdrand", getrandom_backend = "rndr"))))'.dependencies.libc]
version = "0.2.154" version = "0.2.154"
default-features = false default-features = false
@@ -98,13 +98,14 @@ optional = true
default-features = false default-features = false
[target.'cfg(all(target_arch = "wasm32", target_os = "wasi", target_env = "p2"))'.dependencies.wasi] [target.'cfg(all(target_arch = "wasm32", target_os = "wasi", target_env = "p2"))'.dependencies.wasi]
version = "0.13" version = "0.14"
default-features = false default-features = false
[target.'cfg(all(windows, not(target_vendor = "win7")))'.dependencies.windows-targets] [target.'cfg(all(target_os = "uefi", getrandom_backend = "efi_rng"))'.dependencies.r-efi]
version = "0.52" version = "5.1"
default-features = false
[target.'cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "hurd", target_os = "illumos", all(target_os = "horizon", target_arch = "arm")))'.dependencies.libc] [target.'cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "hurd", target_os = "illumos", target_os = "cygwin", all(target_os = "horizon", target_arch = "arm")))'.dependencies.libc]
version = "0.2.154" version = "0.2.154"
default-features = false default-features = false
@@ -136,8 +137,11 @@ default-features = false
level = "warn" level = "warn"
priority = 0 priority = 0
check-cfg = [ check-cfg = [
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "wasm_js"))', 'cfg(getrandom_backend, values("custom", "efi_rng", "rdrand", "rndr", "linux_getrandom", "linux_raw", "wasm_js"))',
"cfg(getrandom_msan)", "cfg(getrandom_msan)",
"cfg(getrandom_windows_legacy)",
"cfg(getrandom_test_linux_fallback)", "cfg(getrandom_test_linux_fallback)",
"cfg(getrandom_test_linux_without_fallback)",
"cfg(getrandom_test_netbsd_fallback)", "cfg(getrandom_test_netbsd_fallback)",
'cfg(target_os, values("cygwin"))',
] ]

View File

@@ -1,4 +1,4 @@
Copyright (c) 2018-2024 The rust-random Project Developers Copyright (c) 2018-2025 The rust-random Project Developers
Copyright (c) 2014 The Rust Project Developers Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any Permission is hereby granted, free of charge, to any

View File

@@ -43,7 +43,7 @@ fn get_random_u128() -> Result<u128, getrandom::Error> {
| Target | Target Triple | Implementation | Target | Target Triple | Implementation
| ------------------ | ------------------ | -------------- | ------------------ | ------------------ | --------------
| Linux, Android | `*linux*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random` | Linux, Android | `*linux*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
| Windows 10+ | `*windows*` | [`ProcessPrng`] | Windows 10+ | `*windows*` | [`ProcessPrng`] on Rust 1.78+, [`RtlGenRandom`] otherwise
| Windows 7, 8 | `*-win7windows*` | [`RtlGenRandom`] | Windows 7, 8 | `*-win7windows*` | [`RtlGenRandom`]
| macOS | `*appledarwin` | [`getentropy`][3] | macOS | `*appledarwin` | [`getentropy`][3]
| iOS, tvOS, watchOS | `*apple{ios,tvos,watchos}` | [`CCRandomGenerateBytes`] | iOS, tvOS, watchOS | `*apple{ios,tvos,watchos}` | [`CCRandomGenerateBytes`]
@@ -69,6 +69,7 @@ fn get_random_u128() -> Result<u128, getrandom::Error> {
| PS Vita | `*-vita-*` | [`getentropy`][19] | PS Vita | `*-vita-*` | [`getentropy`][19]
| QNX Neutrino | `*nto-qnx*` | [`/dev/urandom`][14] (identical to `/dev/random`) | QNX Neutrino | `*nto-qnx*` | [`/dev/urandom`][14] (identical to `/dev/random`)
| AIX | `*-ibm-aix` | [`/dev/urandom`][15] | AIX | `*-ibm-aix` | [`/dev/urandom`][15]
| Cygwin | `*-cygwin` | [`getrandom`][20] (based on [`RtlGenRandom`])
Pull Requests that add support for new targets to `getrandom` are always welcome. Pull Requests that add support for new targets to `getrandom` are always welcome.
@@ -80,15 +81,22 @@ of randomness based on their specific needs:
| Backend name | Target | Target Triple | Implementation | Backend name | Target | Target Triple | Implementation
| ----------------- | -------------------- | ------------------------ | -------------- | ----------------- | -------------------- | ------------------------ | --------------
| `linux_getrandom` | Linux, Android | `*linux*` | [`getrandom`][1] system call (without `/dev/urandom` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow). | `linux_getrandom` | Linux, Android | `*linux*` | [`getrandom`][1] system call (without `/dev/urandom` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow).
| `linux_raw` | Linux, Android | `*linux*` | Same as `linux_getrandom`, but uses raw `asm!`-based syscalls instead of `libc`.
| `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction | `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction
| `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register | `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register
| `wasm_js` | Web Browser, Node.js | `wasm32unknownunknown`, `wasm32v1-none` | [`Crypto.getRandomValues`]. Requires feature `wasm_js` ([see below](#webassembly-support)). | `wasm_js` | Web Browser, Node.js | `wasm32unknownunknown`, `wasm32v1-none` | [`Crypto.getRandomValues`]. Requires feature `wasm_js` ([see below](#webassembly-support)).
| `efi_rng` | UEFI | `*-unknownuefi` | [`EFI_RNG_PROTOCOL`] with `EFI_RNG_ALGORITHM_RAW` (requires `std` and Nigthly compiler)
| `custom` | All targets | `*` | User-provided custom implementation (see [custom backend]) | `custom` | All targets | `*` | User-provided custom implementation (see [custom backend])
Opt-in backends can be enabled using the `getrandom_backend` configuration flag. Opt-in backends can be enabled using the `getrandom_backend` configuration flag.
The flag can be set either by specifying the `rustflags` field in The flag can be set either by specifying the `rustflags` field in [`.cargo/config.toml`]:
[`.cargo/config.toml`] (note that it can be done on a per-target basis), or by using ```toml
the `RUSTFLAGS` environment variable: # It's recommended to set the flag on a per-target basis:
[target.wasm32-unknown-unknown]
rustflags = ['--cfg', 'getrandom_backend="wasm_js"']
```
Or by using the `RUSTFLAGS` environment variable:
```sh ```sh
RUSTFLAGS='--cfg getrandom_backend="linux_getrandom"' cargo build RUSTFLAGS='--cfg getrandom_backend="linux_getrandom"' cargo build
@@ -105,6 +113,15 @@ WILL NOT have any effect on its downstream users.
[`.cargo/config.toml`]: https://doc.rust-lang.org/cargo/reference/config.html [`.cargo/config.toml`]: https://doc.rust-lang.org/cargo/reference/config.html
### Raw Linux syscall support
Currently the `linux_raw` backend supports only targets with stabilized `asm!` macro,
i.e. `arm`, `aarch64`, `loongarch64`, `riscv32`, `riscv64`, `s390x`, `x86`, and `x86_64`.
Note that the raw syscall backend may be slower than backends based on `libc::getrandom`,
e.g. it does not implement vDSO optimizations and on `x86` it uses the infamously slow
`int 0x80` instruction to perform syscall.
### WebAssembly support ### WebAssembly support
This crate fully supports the [WASI] and [Emscripten] targets. However, This crate fully supports the [WASI] and [Emscripten] targets. However,
@@ -113,7 +130,7 @@ is not automatically supported since, from the target name alone, we cannot dedu
which JavaScript interface should be used (or if JavaScript is available at all). which JavaScript interface should be used (or if JavaScript is available at all).
To enable `getrandom`'s functionality on `wasm32-unknown-unknown` using the Web To enable `getrandom`'s functionality on `wasm32-unknown-unknown` using the Web
Crypto methods [described above](#opt-in-backends) via [`wasm-bindgen`], do Crypto methods [described above][opt-in] via [`wasm-bindgen`], do
*both* of the following: *both* of the following:
- Use the `wasm_js` feature flag, i.e. - Use the `wasm_js` feature flag, i.e.
@@ -121,18 +138,22 @@ Crypto methods [described above](#opt-in-backends) via [`wasm-bindgen`], do
On its own, this only makes the backend available. (As a side effect this On its own, this only makes the backend available. (As a side effect this
will make your `Cargo.lock` significantly larger if you are not already will make your `Cargo.lock` significantly larger if you are not already
using [`wasm-bindgen`], but otherwise enabling this feature is harmless.) using [`wasm-bindgen`], but otherwise enabling this feature is harmless.)
- Set `RUSTFLAGS='--cfg getrandom_backend="wasm_js"'` ([see above](#opt-in-backends)). - Set `RUSTFLAGS='--cfg getrandom_backend="wasm_js"'` ([see above][opt-in]).
This backend supports both web browsers (main window and Web Workers) This backend supports both web browsers (main window and Web Workers)
and Node.js (v19 or later) environments. and Node.js (v19 or later) environments.
WARNING: It is highly recommended to enable the `wasm_js` feature only for
binary crates and tests, i.e. avoid unconditionally enabling it in library crates.
### Custom backend ### Custom backend
If this crate does not support your target out of the box or you have to use If this crate does not support your target out of the box or you have to use
a non-default entropy source, then you can provide a custom implementation. a non-default entropy source, then you can provide a custom implementation.
You need to enable the custom backend as described in the [configuration flags] You need to enable the custom backend as described in the
section. Next, you need to define an `extern` function with the following [opt-in backends][opt-in] section.
signature:
Next, you need to define an `extern` function with the following signature:
```rust ```rust
use getrandom::Error; use getrandom::Error;
@@ -305,7 +326,7 @@ dual licensed as above, without any additional terms or conditions.
[//]: # (badges) [//]: # (badges)
[GitHub Actions]: https://github.com/rust-random/getrandom/actions?query=workflow:Tests+branch:master [GitHub Actions]: https://github.com/rust-random/getrandom/actions?query=branch:master
[Build Status]: https://github.com/rust-random/getrandom/actions/workflows/tests.yml/badge.svg?branch=master [Build Status]: https://github.com/rust-random/getrandom/actions/workflows/tests.yml/badge.svg?branch=master
[crates.io]: https://crates.io/crates/getrandom [crates.io]: https://crates.io/crates/getrandom
[Crate]: https://img.shields.io/crates/v/getrandom [Crate]: https://img.shields.io/crates/v/getrandom
@@ -335,6 +356,7 @@ dual licensed as above, without any additional terms or conditions.
[17]: https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getrandom [17]: https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getrandom
[18]: https://github.com/rust3ds/shim-3ds/commit/b01d2568836dea2a65d05d662f8e5f805c64389d [18]: https://github.com/rust3ds/shim-3ds/commit/b01d2568836dea2a65d05d662f8e5f805c64389d
[19]: https://github.com/vitasdk/newlib/blob/2d869fe47aaf02b8e52d04e9a2b79d5b210fd016/newlib/libc/sys/vita/getentropy.c [19]: https://github.com/vitasdk/newlib/blob/2d869fe47aaf02b8e52d04e9a2b79d5b210fd016/newlib/libc/sys/vita/getentropy.c
[20]: https://github.com/cygwin/cygwin/blob/main/winsup/cygwin/libc/getentropy.cc
[`ProcessPrng`]: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng [`ProcessPrng`]: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng
[`RtlGenRandom`]: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom [`RtlGenRandom`]: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
@@ -346,6 +368,7 @@ dual licensed as above, without any additional terms or conditions.
[`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html#functions [`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html#functions
[esp-idf-rng]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html [esp-idf-rng]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html
[esp-trng-docs]: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#rng [esp-trng-docs]: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#rng
[`EFI_RNG_PROTOCOL`]: https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#efi-rng-protocol
[`random_get`]: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno [`random_get`]: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno
[`get-random-u64`]: https://github.com/WebAssembly/WASI/blob/v0.2.1/wasip2/random/random.wit#L23-L28 [`get-random-u64`]: https://github.com/WebAssembly/WASI/blob/v0.2.1/wasip2/random/random.wit#L23-L28
[configuration flags]: #configuration-flags [configuration flags]: #configuration-flags
@@ -354,8 +377,9 @@ dual licensed as above, without any additional terms or conditions.
[`module`]: https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-js-imports/module.html [`module`]: https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-js-imports/module.html
[`sys_read_entropy`]: https://github.com/hermit-os/kernel/blob/315f58ff5efc81d9bf0618af85a59963ff55f8b1/src/syscalls/entropy.rs#L47-L55 [`sys_read_entropy`]: https://github.com/hermit-os/kernel/blob/315f58ff5efc81d9bf0618af85a59963ff55f8b1/src/syscalls/entropy.rs#L47-L55
[platform-support]: https://doc.rust-lang.org/stable/rustc/platform-support.html [platform-support]: https://doc.rust-lang.org/stable/rustc/platform-support.html
[WASI]: https://github.com/CraneStation/wasi [WASI]: https://github.com/WebAssembly/WASI
[Emscripten]: https://www.hellorust.com/setup/emscripten/ [Emscripten]: https://emscripten.org
[opt-in]: #opt-in-backends
[//]: # (licenses) [//]: # (licenses)

View File

@@ -1,9 +1,57 @@
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't use std::{env, ffi::OsString, process::Command};
// supported. Build scripts get cfg() info, even if the cfg is unstable.
/// Tries to get the minor version of the Rust compiler in use.
/// If it fails for any reason, returns `None`.
///
/// Based on the `rustc_version` crate.
fn rustc_minor_version() -> Option<u64> {
let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER").filter(|w| !w.is_empty()) {
let mut cmd = Command::new(wrapper);
cmd.arg(rustc);
cmd
} else {
Command::new(rustc)
};
let out = cmd.arg("-vV").output().ok()?;
if !out.status.success() {
return None;
}
let stdout = std::str::from_utf8(&out.stdout).ok()?;
// Assumes that the first line contains "rustc 1.xx.0-channel (abcdef 2025-01-01)"
// where "xx" is the minor version which we want to extract
let mut lines = stdout.lines();
let first_line = lines.next()?;
let minor_ver_str = first_line.split(".").nth(1)?;
minor_ver_str.parse().ok()
}
fn main() { fn main() {
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't
// supported. Build scripts get cfg() info, even if the cfg is unstable.
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
let santizers = std::env::var("CARGO_CFG_SANITIZE").unwrap_or_default(); let santizers = std::env::var("CARGO_CFG_SANITIZE").unwrap_or_default();
if santizers.contains("memory") { if santizers.contains("memory") {
println!("cargo:rustc-cfg=getrandom_msan"); println!("cargo:rustc-cfg=getrandom_msan");
} }
// Use `RtlGenRandom` on older compiler versions since win7 targets
// TODO(MSRV 1.78): Remove this check
let target_family = env::var_os("CARGO_CFG_TARGET_FAMILY").and_then(|f| f.into_string().ok());
if target_family.as_deref() == Some("windows") {
/// Minor version of the Rust compiler in which win7 targets were inroduced
const WIN7_INTRODUCED_MINOR_VER: u64 = 78;
match rustc_minor_version() {
Some(minor_ver) if minor_ver < WIN7_INTRODUCED_MINOR_VER => {
println!("cargo:rustc-cfg=getrandom_windows_legacy");
}
None => println!("cargo:warning=Couldn't detect minor version of the Rust compiler"),
_ => {}
}
}
} }

View File

@@ -11,27 +11,36 @@ cfg_if! {
mod custom; mod custom;
pub use custom::*; pub use custom::*;
} else if #[cfg(getrandom_backend = "linux_getrandom")] { } else if #[cfg(getrandom_backend = "linux_getrandom")] {
mod linux_android; mod getrandom;
pub use linux_android::*; pub use getrandom::*;
} else if #[cfg(getrandom_backend = "linux_raw")] {
mod linux_raw;
pub use linux_raw::*;
} else if #[cfg(getrandom_backend = "rdrand")] { } else if #[cfg(getrandom_backend = "rdrand")] {
mod rdrand; mod rdrand;
pub use rdrand::*; pub use rdrand::*;
} else if #[cfg(getrandom_backend = "rndr")] { } else if #[cfg(getrandom_backend = "rndr")] {
mod rndr; mod rndr;
pub use rndr::*; pub use rndr::*;
} else if #[cfg(getrandom_backend = "efi_rng")] {
mod efi_rng;
pub use efi_rng::*;
} else if #[cfg(all(getrandom_backend = "wasm_js"))] { } else if #[cfg(all(getrandom_backend = "wasm_js"))] {
cfg_if! { cfg_if! {
if #[cfg(feature = "wasm_js")] { if #[cfg(feature = "wasm_js")] {
mod wasm_js; mod wasm_js;
pub use wasm_js::*; pub use wasm_js::*;
} else { } else {
compile_error!( compile_error!(concat!(
"The \"wasm_js\" backend requires the `wasm_js` feature \ "The \"wasm_js\" backend requires the `wasm_js` feature \
for `getrandom`. For more information see: \ for `getrandom`. For more information see: \
https://docs.rs/getrandom/#webassembly-support" https://docs.rs/getrandom/", env!("CARGO_PKG_VERSION"), "/#webassembly-support"
); ));
} }
} }
} else if #[cfg(all(target_os = "linux", target_env = ""))] {
mod linux_raw;
pub use linux_raw::*;
} else if #[cfg(target_os = "espidf")] { } else if #[cfg(target_os = "espidf")] {
mod esp_idf; mod esp_idf;
pub use esp_idf::*; pub use esp_idf::*;
@@ -51,17 +60,6 @@ cfg_if! {
))] { ))] {
mod getentropy; mod getentropy;
pub use getentropy::*; pub use getentropy::*;
} else if #[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",
target_os = "illumos",
// Check for target_arch = "arm" to only include the 3DS. Does not
// include the Nintendo Switch (which is target_arch = "aarch64").
all(target_os = "horizon", target_arch = "arm"),
))] {
mod getrandom;
pub use getrandom::*;
} else if #[cfg(any( } else if #[cfg(any(
// Rust supports Android API level 19 (KitKat) [0] and the next upgrade targets // Rust supports Android API level 19 (KitKat) [0] and the next upgrade targets
// level 21 (Lollipop) [1], while `getrandom(2)` was added only in // level 21 (Lollipop) [1], while `getrandom(2)` was added only in
@@ -102,9 +100,20 @@ cfg_if! {
mod use_file; mod use_file;
mod linux_android_with_fallback; mod linux_android_with_fallback;
pub use linux_android_with_fallback::*; pub use linux_android_with_fallback::*;
} else if #[cfg(any(target_os = "android", target_os = "linux"))] { } else if #[cfg(any(
mod linux_android; target_os = "android",
pub use linux_android::*; target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",
target_os = "illumos",
target_os = "cygwin",
// Check for target_arch = "arm" to only include the 3DS. Does not
// include the Nintendo Switch (which is target_arch = "aarch64").
all(target_os = "horizon", target_arch = "arm"),
))] {
mod getrandom;
pub use getrandom::*;
} else if #[cfg(target_os = "solaris")] { } else if #[cfg(target_os = "solaris")] {
mod solaris; mod solaris;
pub use solaris::*; pub use solaris::*;
@@ -146,7 +155,7 @@ cfg_if! {
} else if #[cfg(target_os = "solid_asp3")] { } else if #[cfg(target_os = "solid_asp3")] {
mod solid; mod solid;
pub use solid::*; pub use solid::*;
} else if #[cfg(all(windows, target_vendor = "win7"))] { } else if #[cfg(all(windows, any(target_vendor = "win7", getrandom_windows_legacy)))] {
mod windows7; mod windows7;
pub use windows7::*; pub use windows7::*;
} else if #[cfg(windows)] { } else if #[cfg(windows)] {
@@ -156,16 +165,17 @@ cfg_if! {
mod rdrand; mod rdrand;
pub use rdrand::*; pub use rdrand::*;
} else if #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))] { } else if #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))] {
compile_error!( compile_error!(concat!(
"The wasm32-unknown-unknown targets are not supported by default; \ "The wasm32-unknown-unknown targets are not supported by default; \
you may need to enable the \"wasm_js\" configuration flag. Note \ you may need to enable the \"wasm_js\" configuration flag. Note \
that enabling the `wasm_js` feature flag alone is insufficient. \ that enabling the `wasm_js` feature flag alone is insufficient. \
For more information see: \ For more information see: \
https://docs.rs/getrandom/#webassembly-support" https://docs.rs/getrandom/", env!("CARGO_PKG_VERSION"), "/#webassembly-support"
); ));
} else { } else {
compile_error!("target is not supported. You may need to define \ compile_error!(concat!(
a custom backend see: \ "target is not supported. You may need to define a custom backend see: \
https://docs.rs/getrandom/#custom-backends"); https://docs.rs/getrandom/", env!("CARGO_PKG_VERSION"), "/#custom-backend"
));
} }
} }

View File

@@ -4,6 +4,7 @@ use core::{ffi::c_void, mem::MaybeUninit};
pub use crate::util::{inner_u32, inner_u64}; pub use crate::util::{inner_u32, inner_u64};
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let dst_ptr = dest.as_mut_ptr().cast::<c_void>(); let dst_ptr = dest.as_mut_ptr().cast::<c_void>();
let ret = unsafe { libc::CCRandomGenerateBytes(dst_ptr, dest.len()) }; let ret = unsafe { libc::CCRandomGenerateBytes(dst_ptr, dest.len()) };

View File

@@ -4,6 +4,7 @@ use core::mem::MaybeUninit;
pub use crate::util::{inner_u32, inner_u64}; pub use crate::util::{inner_u32, inner_u64};
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
extern "Rust" { extern "Rust" {
fn __getrandom_v03_custom(dest: *mut u8, len: usize) -> Result<(), Error>; fn __getrandom_v03_custom(dest: *mut u8, len: usize) -> Result<(), Error>;

View File

@@ -0,0 +1,124 @@
//! Implementation for UEFI using EFI_RNG_PROTOCOL
use crate::Error;
use core::{
mem::MaybeUninit,
ptr::{self, null_mut, NonNull},
sync::atomic::{AtomicPtr, Ordering::Relaxed},
};
use r_efi::{
efi::{BootServices, Handle},
protocols::rng,
};
extern crate std;
pub use crate::util::{inner_u32, inner_u64};
#[cfg(not(target_os = "uefi"))]
compile_error!("`efi_rng` backend can be enabled only for UEFI targets!");
static RNG_PROTOCOL: AtomicPtr<rng::Protocol> = AtomicPtr::new(null_mut());
#[cold]
#[inline(never)]
fn init() -> Result<NonNull<rng::Protocol>, Error> {
const HANDLE_SIZE: usize = size_of::<Handle>();
let boot_services = std::os::uefi::env::boot_services()
.ok_or(Error::BOOT_SERVICES_UNAVAILABLE)?
.cast::<BootServices>();
let mut handles = [ptr::null_mut(); 16];
// `locate_handle` operates with length in bytes
let mut buf_size = handles.len() * HANDLE_SIZE;
let mut guid = rng::PROTOCOL_GUID;
let ret = unsafe {
((*boot_services.as_ptr()).locate_handle)(
r_efi::efi::BY_PROTOCOL,
&mut guid,
null_mut(),
&mut buf_size,
handles.as_mut_ptr(),
)
};
if ret.is_error() {
return Err(Error::from_uefi_code(ret.as_usize()));
}
let handles_len = buf_size / HANDLE_SIZE;
let handles = handles.get(..handles_len).ok_or(Error::UNEXPECTED)?;
let system_handle = std::os::uefi::env::image_handle();
for &handle in handles {
let mut protocol: MaybeUninit<*mut rng::Protocol> = MaybeUninit::uninit();
let mut protocol_guid = rng::PROTOCOL_GUID;
let ret = unsafe {
((*boot_services.as_ptr()).open_protocol)(
handle,
&mut protocol_guid,
protocol.as_mut_ptr().cast(),
system_handle.as_ptr(),
ptr::null_mut(),
r_efi::system::OPEN_PROTOCOL_GET_PROTOCOL,
)
};
let protocol = if ret.is_error() {
continue;
} else {
let protocol = unsafe { protocol.assume_init() };
NonNull::new(protocol).ok_or(Error::UNEXPECTED)?
};
// Try to use the acquired protocol handle
let mut buf = [0u8; 8];
let mut alg_guid = rng::ALGORITHM_RAW;
let ret = unsafe {
((*protocol.as_ptr()).get_rng)(
protocol.as_ptr(),
&mut alg_guid,
buf.len(),
buf.as_mut_ptr(),
)
};
if ret.is_error() {
continue;
}
RNG_PROTOCOL.store(protocol.as_ptr(), Relaxed);
return Ok(protocol);
}
Err(Error::NO_RNG_HANDLE)
}
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let protocol = match NonNull::new(RNG_PROTOCOL.load(Relaxed)) {
Some(p) => p,
None => init()?,
};
let mut alg_guid = rng::ALGORITHM_RAW;
let ret = unsafe {
((*protocol.as_ptr()).get_rng)(
protocol.as_ptr(),
&mut alg_guid,
dest.len(),
dest.as_mut_ptr().cast::<u8>(),
)
};
if ret.is_error() {
Err(Error::from_uefi_code(ret.as_usize()))
} else {
Ok(())
}
}
impl Error {
pub(crate) const BOOT_SERVICES_UNAVAILABLE: Error = Self::new_internal(10);
pub(crate) const NO_RNG_HANDLE: Error = Self::new_internal(11);
}

View File

@@ -8,6 +8,7 @@ extern "C" {
fn esp_fill_random(buf: *mut c_void, len: usize) -> u32; fn esp_fill_random(buf: *mut c_void, len: usize) -> u32;
} }
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Not that NOT enabling WiFi, BT, or the voltage noise entropy source (via `bootloader_random_enable`) // Not that NOT enabling WiFi, BT, or the voltage noise entropy source (via `bootloader_random_enable`)
// will cause ESP-IDF to return pseudo-random numbers based on the voltage noise entropy, after the initial boot process: // will cause ESP-IDF to return pseudo-random numbers based on the voltage noise entropy, after the initial boot process:

View File

@@ -9,6 +9,7 @@ extern "C" {
fn zx_cprng_draw(buffer: *mut u8, length: usize); fn zx_cprng_draw(buffer: *mut u8, length: usize);
} }
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
unsafe { zx_cprng_draw(dest.as_mut_ptr().cast::<u8>(), dest.len()) } unsafe { zx_cprng_draw(dest.as_mut_ptr().cast::<u8>(), dest.len()) }
Ok(()) Ok(())

View File

@@ -15,6 +15,7 @@ pub use crate::util::{inner_u32, inner_u64};
#[path = "../util_libc.rs"] #[path = "../util_libc.rs"]
mod util_libc; mod util_libc;
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
for chunk in dest.chunks_mut(256) { for chunk in dest.chunks_mut(256) {
let ret = unsafe { libc::getentropy(chunk.as_mut_ptr().cast::<c_void>(), chunk.len()) }; let ret = unsafe { libc::getentropy(chunk.as_mut_ptr().cast::<c_void>(), chunk.len()) };

View File

@@ -16,15 +16,16 @@
//! nothing. On illumos, the default pool is used to implement getentropy(2), //! nothing. On illumos, the default pool is used to implement getentropy(2),
//! so we assume it is acceptable here. //! so we assume it is acceptable here.
use crate::Error; use crate::Error;
use core::{ffi::c_void, mem::MaybeUninit}; use core::mem::MaybeUninit;
pub use crate::util::{inner_u32, inner_u64}; pub use crate::util::{inner_u32, inner_u64};
#[path = "../util_libc.rs"] #[path = "../util_libc.rs"]
mod util_libc; mod util_libc;
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
util_libc::sys_fill_exact(dest, |buf| unsafe { util_libc::sys_fill_exact(dest, |buf| unsafe {
libc::getrandom(buf.as_mut_ptr().cast::<c_void>(), buf.len(), 0) libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0)
}) })
} }

View File

@@ -12,6 +12,7 @@ extern "C" {
fn sys_secure_rand64(value: *mut u64) -> i32; fn sys_secure_rand64(value: *mut u64) -> i32;
} }
#[inline]
pub fn inner_u32() -> Result<u32, Error> { pub fn inner_u32() -> Result<u32, Error> {
let mut res = MaybeUninit::uninit(); let mut res = MaybeUninit::uninit();
let ret = unsafe { sys_secure_rand32(res.as_mut_ptr()) }; let ret = unsafe { sys_secure_rand32(res.as_mut_ptr()) };
@@ -22,6 +23,7 @@ pub fn inner_u32() -> Result<u32, Error> {
} }
} }
#[inline]
pub fn inner_u64() -> Result<u64, Error> { pub fn inner_u64() -> Result<u64, Error> {
let mut res = MaybeUninit::uninit(); let mut res = MaybeUninit::uninit();
let ret = unsafe { sys_secure_rand64(res.as_mut_ptr()) }; let ret = unsafe { sys_secure_rand64(res.as_mut_ptr()) };
@@ -32,6 +34,7 @@ pub fn inner_u64() -> Result<u64, Error> {
} }
} }
#[inline]
pub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
while !dest.is_empty() { while !dest.is_empty() {
let res = unsafe { sys_read_entropy(dest.as_mut_ptr().cast::<u8>(), dest.len(), 0) }; let res = unsafe { sys_read_entropy(dest.as_mut_ptr().cast::<u8>(), dest.len(), 0) };
@@ -41,10 +44,8 @@ pub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
dest = dest.get_mut(len..).ok_or(Error::UNEXPECTED)?; dest = dest.get_mut(len..).ok_or(Error::UNEXPECTED)?;
} }
code => { code => {
let err = u32::try_from(code.unsigned_abs()) let code = i32::try_from(code).map_err(|_| Error::UNEXPECTED)?;
.ok() return Err(Error::from_neg_error_code(code));
.map_or(Error::UNEXPECTED, Error::from_os_error);
return Err(err);
} }
} }
} }

View File

@@ -1,17 +0,0 @@
//! Implementation for Linux / Android without `/dev/urandom` fallback
use crate::Error;
use core::mem::MaybeUninit;
pub use crate::util::{inner_u32, inner_u64};
#[path = "../util_libc.rs"]
mod util_libc;
#[cfg(not(any(target_os = "android", target_os = "linux")))]
compile_error!("`linux_getrandom` backend can be enabled only for Linux/Android targets!");
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
util_libc::sys_fill_exact(dest, |buf| unsafe {
libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0)
})
}

View File

@@ -3,8 +3,8 @@ use super::use_file;
use crate::Error; use crate::Error;
use core::{ use core::{
ffi::c_void, ffi::c_void,
mem::{self, MaybeUninit}, mem::{transmute, MaybeUninit},
ptr::{self, NonNull}, ptr::NonNull,
sync::atomic::{AtomicPtr, Ordering}, sync::atomic::{AtomicPtr, Ordering},
}; };
use use_file::util_libc; use use_file::util_libc;
@@ -17,17 +17,28 @@ type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint)
/// or not supported by kernel. /// or not supported by kernel.
const NOT_AVAILABLE: NonNull<c_void> = unsafe { NonNull::new_unchecked(usize::MAX as *mut c_void) }; const NOT_AVAILABLE: NonNull<c_void> = unsafe { NonNull::new_unchecked(usize::MAX as *mut c_void) };
static GETRANDOM_FN: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut()); static GETRANDOM_FN: AtomicPtr<c_void> = AtomicPtr::new(core::ptr::null_mut());
#[cold] #[cold]
#[inline(never)]
fn init() -> NonNull<c_void> { fn init() -> NonNull<c_void> {
static NAME: &[u8] = b"getrandom\0"; // Use static linking to `libc::getrandom` on MUSL targets and `dlsym` everywhere else
let name_ptr = NAME.as_ptr().cast::<libc::c_char>(); #[cfg(not(target_env = "musl"))]
let raw_ptr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, name_ptr) }; let raw_ptr = {
static NAME: &[u8] = b"getrandom\0";
let name_ptr = NAME.as_ptr().cast::<libc::c_char>();
unsafe { libc::dlsym(libc::RTLD_DEFAULT, name_ptr) }
};
#[cfg(target_env = "musl")]
let raw_ptr = {
let fptr: GetRandomFn = libc::getrandom;
unsafe { transmute::<GetRandomFn, *mut c_void>(fptr) }
};
let res_ptr = match NonNull::new(raw_ptr) { let res_ptr = match NonNull::new(raw_ptr) {
Some(fptr) => { Some(fptr) => {
let getrandom_fn = unsafe { mem::transmute::<NonNull<c_void>, GetRandomFn>(fptr) }; let getrandom_fn = unsafe { transmute::<NonNull<c_void>, GetRandomFn>(fptr) };
let dangling_ptr = ptr::NonNull::dangling().as_ptr(); let dangling_ptr = NonNull::dangling().as_ptr();
// Check that `getrandom` syscall is supported by kernel // Check that `getrandom` syscall is supported by kernel
let res = unsafe { getrandom_fn(dangling_ptr, 0, 0) }; let res = unsafe { getrandom_fn(dangling_ptr, 0, 0) };
if cfg!(getrandom_test_linux_fallback) { if cfg!(getrandom_test_linux_fallback) {
@@ -49,16 +60,22 @@ fn init() -> NonNull<c_void> {
None => NOT_AVAILABLE, None => NOT_AVAILABLE,
}; };
#[cfg(getrandom_test_linux_without_fallback)]
if res_ptr == NOT_AVAILABLE {
panic!("Fallback is triggered with enabled `getrandom_test_linux_without_fallback`")
}
GETRANDOM_FN.store(res_ptr.as_ptr(), Ordering::Release); GETRANDOM_FN.store(res_ptr.as_ptr(), Ordering::Release);
res_ptr res_ptr
} }
// prevent inlining of the fallback implementation // Prevent inlining of the fallback implementation
#[inline(never)] #[inline(never)]
fn use_file_fallback(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { fn use_file_fallback(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
use_file::fill_inner(dest) use_file::fill_inner(dest)
} }
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Despite being only a single atomic variable, we still cannot always use // Despite being only a single atomic variable, we still cannot always use
// Ordering::Relaxed, as we need to make sure a successful call to `init` // Ordering::Relaxed, as we need to make sure a successful call to `init`
@@ -75,8 +92,8 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
if fptr == NOT_AVAILABLE { if fptr == NOT_AVAILABLE {
use_file_fallback(dest) use_file_fallback(dest)
} else { } else {
// note: `transume` is currently the only way to convert pointer into function reference // note: `transmute` is currently the only way to convert a pointer into a function reference
let getrandom_fn = unsafe { mem::transmute::<NonNull<c_void>, GetRandomFn>(fptr) }; let getrandom_fn = unsafe { transmute::<NonNull<c_void>, GetRandomFn>(fptr) };
util_libc::sys_fill_exact(dest, |buf| unsafe { util_libc::sys_fill_exact(dest, |buf| unsafe {
getrandom_fn(buf.as_mut_ptr().cast(), buf.len(), 0) getrandom_fn(buf.as_mut_ptr().cast(), buf.len(), 0)
}) })

View File

@@ -0,0 +1,136 @@
//! Implementation for Linux / Android using `asm!`-based syscalls.
use crate::{Error, MaybeUninit};
pub use crate::util::{inner_u32, inner_u64};
#[cfg(not(any(target_os = "android", target_os = "linux")))]
compile_error!("`linux_raw` backend can be enabled only for Linux/Android targets!");
#[allow(non_upper_case_globals)]
unsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize {
let r0;
// Based on `rustix` and `linux-raw-sys` code.
cfg_if! {
if #[cfg(target_arch = "arm")] {
const __NR_getrandom: u32 = 384;
// In thumb-mode, r7 is the frame pointer and is not permitted to be used in
// an inline asm operand, so we have to use a different register and copy it
// into r7 inside the inline asm.
// Theoretically, we could detect thumb mode in the build script, but several
// register moves are cheap enough compared to the syscall cost, so we do not
// bother with it.
core::arch::asm!(
"mov {tmp}, r7",
"mov r7, {nr}",
"svc 0",
"mov r7, {tmp}",
nr = const __NR_getrandom,
tmp = out(reg) _,
inlateout("r0") buf => r0,
in("r1") buflen,
in("r2") flags,
options(nostack, preserves_flags)
);
} else if #[cfg(target_arch = "aarch64")] {
const __NR_getrandom: u32 = 278;
core::arch::asm!(
"svc 0",
in("x8") __NR_getrandom,
inlateout("x0") buf => r0,
in("x1") buflen,
in("x2") flags,
options(nostack, preserves_flags)
);
} else if #[cfg(target_arch = "loongarch64")] {
const __NR_getrandom: u32 = 278;
core::arch::asm!(
"syscall 0",
in("$a7") __NR_getrandom,
inlateout("$a0") buf => r0,
in("$a1") buflen,
in("$a2") flags,
options(nostack, preserves_flags)
);
} else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] {
const __NR_getrandom: u32 = 278;
core::arch::asm!(
"ecall",
in("a7") __NR_getrandom,
inlateout("a0") buf => r0,
in("a1") buflen,
in("a2") flags,
options(nostack, preserves_flags)
);
} else if #[cfg(target_arch = "s390x")] {
const __NR_getrandom: u32 = 349;
core::arch::asm!(
"svc 0",
in("r1") __NR_getrandom,
inlateout("r2") buf => r0,
in("r3") buflen,
in("r4") flags,
options(nostack, preserves_flags)
);
} else if #[cfg(target_arch = "x86")] {
const __NR_getrandom: u32 = 355;
// `int 0x80` is famously slow, but implementing vDSO is too complex
// and `sysenter`/`syscall` have their own portability issues,
// so we use the simple "legacy" way of doing syscalls.
core::arch::asm!(
"int $$0x80",
in("eax") __NR_getrandom,
in("ebx") buf,
in("ecx") buflen,
in("edx") flags,
lateout("eax") r0,
options(nostack, preserves_flags)
);
} else if #[cfg(target_arch = "x86_64")] {
#[cfg(target_pointer_width = "64")]
const __NR_getrandom: u32 = 318;
#[cfg(target_pointer_width = "32")]
const __NR_getrandom: u32 = (1 << 30) + 318;
core::arch::asm!(
"syscall",
in("rax") __NR_getrandom,
in("rdi") buf,
in("rsi") buflen,
in("rdx") flags,
lateout("rax") r0,
lateout("rcx") _,
lateout("r11") _,
options(nostack, preserves_flags)
);
} else {
compile_error!("`linux_raw` backend does not support this target arch");
}
}
r0
}
#[inline]
pub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Value of this error code is stable across all target arches.
const EINTR: isize = -4;
loop {
let ret = unsafe { getrandom_syscall(dest.as_mut_ptr().cast(), dest.len(), 0) };
match usize::try_from(ret) {
Ok(0) => return Err(Error::UNEXPECTED),
Ok(len) => {
dest = dest.get_mut(len..).ok_or(Error::UNEXPECTED)?;
if dest.is_empty() {
return Ok(());
}
}
Err(_) if ret == EINTR => continue,
Err(_) => {
let code = i32::try_from(ret).map_err(|_| Error::UNEXPECTED)?;
return Err(Error::from_neg_error_code(code));
}
}
}
}

View File

@@ -45,6 +45,7 @@ type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint)
static GETRANDOM: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut()); static GETRANDOM: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
#[cold] #[cold]
#[inline(never)]
fn init() -> *mut c_void { fn init() -> *mut c_void {
static NAME: &[u8] = b"getrandom\0"; static NAME: &[u8] = b"getrandom\0";
let name_ptr = NAME.as_ptr().cast::<libc::c_char>(); let name_ptr = NAME.as_ptr().cast::<libc::c_char>();
@@ -58,6 +59,7 @@ fn init() -> *mut c_void {
ptr ptr
} }
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Despite being only a single atomic variable, we still cannot always use // Despite being only a single atomic variable, we still cannot always use
// Ordering::Relaxed, as we need to make sure a successful call to `init` // Ordering::Relaxed, as we need to make sure a successful call to `init`

View File

@@ -147,6 +147,7 @@ unsafe fn rdrand_u64() -> Option<u64> {
Some((u64::from(a) << 32) | u64::from(b)) Some((u64::from(a) << 32) | u64::from(b))
} }
#[inline]
pub fn inner_u32() -> Result<u32, Error> { pub fn inner_u32() -> Result<u32, Error> {
if !RDRAND_GOOD.unsync_init(is_rdrand_good) { if !RDRAND_GOOD.unsync_init(is_rdrand_good) {
return Err(Error::NO_RDRAND); return Err(Error::NO_RDRAND);
@@ -155,6 +156,7 @@ pub fn inner_u32() -> Result<u32, Error> {
unsafe { rdrand_u32() }.ok_or(Error::FAILED_RDRAND) unsafe { rdrand_u32() }.ok_or(Error::FAILED_RDRAND)
} }
#[inline]
pub fn inner_u64() -> Result<u64, Error> { pub fn inner_u64() -> Result<u64, Error> {
if !RDRAND_GOOD.unsync_init(is_rdrand_good) { if !RDRAND_GOOD.unsync_init(is_rdrand_good) {
return Err(Error::NO_RDRAND); return Err(Error::NO_RDRAND);
@@ -163,6 +165,7 @@ pub fn inner_u64() -> Result<u64, Error> {
unsafe { rdrand_u64() }.ok_or(Error::FAILED_RDRAND) unsafe { rdrand_u64() }.ok_or(Error::FAILED_RDRAND)
} }
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
if !RDRAND_GOOD.unsync_init(is_rdrand_good) { if !RDRAND_GOOD.unsync_init(is_rdrand_good) {
return Err(Error::NO_RDRAND); return Err(Error::NO_RDRAND);

View File

@@ -108,6 +108,7 @@ fn is_rndr_available() -> bool {
} }
} }
#[inline]
pub fn inner_u32() -> Result<u32, Error> { pub fn inner_u32() -> Result<u32, Error> {
if !is_rndr_available() { if !is_rndr_available() {
return Err(Error::RNDR_NOT_AVAILABLE); return Err(Error::RNDR_NOT_AVAILABLE);
@@ -117,6 +118,7 @@ pub fn inner_u32() -> Result<u32, Error> {
res.map(truncate).ok_or(Error::RNDR_FAILURE) res.map(truncate).ok_or(Error::RNDR_FAILURE)
} }
#[inline]
pub fn inner_u64() -> Result<u64, Error> { pub fn inner_u64() -> Result<u64, Error> {
if !is_rndr_available() { if !is_rndr_available() {
return Err(Error::RNDR_NOT_AVAILABLE); return Err(Error::RNDR_NOT_AVAILABLE);
@@ -126,6 +128,7 @@ pub fn inner_u64() -> Result<u64, Error> {
res.ok_or(Error::RNDR_FAILURE) res.ok_or(Error::RNDR_FAILURE)
} }
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
if !is_rndr_available() { if !is_rndr_available() {
return Err(Error::RNDR_NOT_AVAILABLE); return Err(Error::RNDR_NOT_AVAILABLE);

View File

@@ -22,6 +22,7 @@ mod util_libc;
const MAX_BYTES: usize = 1024; const MAX_BYTES: usize = 1024;
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
for chunk in dest.chunks_mut(MAX_BYTES) { for chunk in dest.chunks_mut(MAX_BYTES) {
let ptr = chunk.as_mut_ptr().cast::<c_void>(); let ptr = chunk.as_mut_ptr().cast::<c_void>();

View File

@@ -8,13 +8,12 @@ extern "C" {
pub fn SOLID_RNG_SampleRandomBytes(buffer: *mut u8, length: usize) -> i32; pub fn SOLID_RNG_SampleRandomBytes(buffer: *mut u8, length: usize) -> i32;
} }
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let ret = unsafe { SOLID_RNG_SampleRandomBytes(dest.as_mut_ptr().cast::<u8>(), dest.len()) }; let ret = unsafe { SOLID_RNG_SampleRandomBytes(dest.as_mut_ptr().cast::<u8>(), dest.len()) };
if ret >= 0 { if ret >= 0 {
Ok(()) Ok(())
} else { } else {
// ITRON error numbers are always negative, so we negate it so that it Err(Error::from_neg_error_code(ret))
// falls in the dedicated OS error range (1..INTERNAL_START).
Err(Error::from_os_error(ret.unsigned_abs()))
} }
} }

View File

@@ -40,6 +40,7 @@ const FD_ONGOING_INIT: libc::c_int = -2;
// `Ordering::Acquire` to synchronize with it. // `Ordering::Acquire` to synchronize with it.
static FD: AtomicI32 = AtomicI32::new(FD_UNINIT); static FD: AtomicI32 = AtomicI32::new(FD_UNINIT);
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let mut fd = FD.load(Ordering::Acquire); let mut fd = FD.load(Ordering::Acquire);
if fd == FD_UNINIT || fd == FD_ONGOING_INIT { if fd == FD_UNINIT || fd == FD_ONGOING_INIT {
@@ -57,7 +58,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// TODO: Move `path` to `CStr` and use `CStr::from_bytes_until_nul` (MSRV 1.69) // TODO: Move `path` to `CStr` and use `CStr::from_bytes_until_nul` (MSRV 1.69)
// or C-string literals (MSRV 1.77) for statics // or C-string literals (MSRV 1.77) for statics
fn open_readonly(path: &[u8]) -> Result<libc::c_int, Error> { fn open_readonly(path: &[u8]) -> Result<libc::c_int, Error> {
assert!(path.iter().any(|&b| b == 0)); assert!(path.contains(&0));
loop { loop {
let fd = unsafe { let fd = unsafe {
libc::open( libc::open(
@@ -77,6 +78,7 @@ fn open_readonly(path: &[u8]) -> Result<libc::c_int, Error> {
} }
#[cold] #[cold]
#[inline(never)]
fn open_or_wait() -> Result<libc::c_int, Error> { fn open_or_wait() -> Result<libc::c_int, Error> {
loop { loop {
match FD.load(Ordering::Acquire) { match FD.load(Ordering::Acquire) {

View File

@@ -11,20 +11,25 @@ mod util_libc;
pub use crate::util::{inner_u32, inner_u64}; pub use crate::util::{inner_u32, inner_u64};
static RNG_INIT: AtomicBool = AtomicBool::new(false);
#[cold]
fn init() -> Result<(), Error> {
let ret = unsafe { libc::randSecure() };
match ret.cmp(&0) {
Greater => RNG_INIT.store(true, Relaxed),
Equal => unsafe {
libc::usleep(10);
},
Less => return Err(Error::VXWORKS_RAND_SECURE),
}
Ok(())
}
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
static RNG_INIT: AtomicBool = AtomicBool::new(false);
while !RNG_INIT.load(Relaxed) { while !RNG_INIT.load(Relaxed) {
let ret = unsafe { libc::randSecure() }; init()?;
match ret.cmp(&0) {
Greater => {
RNG_INIT.store(true, Relaxed);
break;
}
Equal => unsafe {
libc::usleep(10);
},
Less => return Err(Error::VXWORKS_RAND_SECURE),
}
} }
// Prevent overflow of i32 // Prevent overflow of i32

View File

@@ -11,6 +11,11 @@ extern "C" {
fn random_get(arg0: i32, arg1: i32) -> i32; fn random_get(arg0: i32, arg1: i32) -> i32;
} }
/// WASI p1 uses `u16` for error codes in its witx definitions:
/// https://github.com/WebAssembly/WASI/blob/38454e9e/legacy/preview1/witx/typenames.witx#L34-L39
const MAX_ERROR_CODE: i32 = u16::MAX as i32;
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Based on the wasi code: // Based on the wasi code:
// https://docs.rs/wasi/0.11.0+wasi-snapshot-preview1/src/wasi/lib_generated.rs.html#2046-2062 // https://docs.rs/wasi/0.11.0+wasi-snapshot-preview1/src/wasi/lib_generated.rs.html#2046-2062
@@ -20,11 +25,8 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let ret = unsafe { random_get(dest.as_mut_ptr() as i32, dest.len() as i32) }; let ret = unsafe { random_get(dest.as_mut_ptr() as i32, dest.len() as i32) };
match ret { match ret {
0 => Ok(()), 0 => Ok(()),
code => { // WASI functions should return positive error codes which are smaller than `MAX_ERROR_CODE`
let err = u32::try_from(code) code if code <= MAX_ERROR_CODE => Err(Error::from_neg_error_code(-code)),
.map(Error::from_os_error) _ => Err(Error::UNEXPECTED),
.unwrap_or(Error::UNEXPECTED);
Err(err)
}
} }
} }

View File

@@ -3,15 +3,18 @@ use crate::Error;
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use wasi::random::random::get_random_u64; use wasi::random::random::get_random_u64;
#[inline]
pub fn inner_u32() -> Result<u32, Error> { pub fn inner_u32() -> Result<u32, Error> {
let val = get_random_u64(); let val = get_random_u64();
Ok(crate::util::truncate(val)) Ok(crate::util::truncate(val))
} }
#[inline]
pub fn inner_u64() -> Result<u64, Error> { pub fn inner_u64() -> Result<u64, Error> {
Ok(get_random_u64()) Ok(get_random_u64())
} }
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
use core::ptr::copy_nonoverlapping; use core::ptr::copy_nonoverlapping;
use wasi::random::random::get_random_u64; use wasi::random::random::get_random_u64;

View File

@@ -14,6 +14,7 @@ use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
const MAX_BUFFER_SIZE: usize = 65536; const MAX_BUFFER_SIZE: usize = 65536;
#[cfg(not(target_feature = "atomics"))] #[cfg(not(target_feature = "atomics"))]
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
for chunk in dest.chunks_mut(MAX_BUFFER_SIZE) { for chunk in dest.chunks_mut(MAX_BUFFER_SIZE) {
if get_random_values(chunk).is_err() { if get_random_values(chunk).is_err() {

View File

@@ -26,14 +26,29 @@ use core::mem::MaybeUninit;
pub use crate::util::{inner_u32, inner_u64}; pub use crate::util::{inner_u32, inner_u64};
// Binding to the Windows.Win32.Security.Cryptography.ProcessPrng API. As // Binding to the Windows.Win32.Security.Cryptography.ProcessPrng API. As
// bcryptprimitives.dll lacks an import library, we use the windows-targets // bcryptprimitives.dll lacks an import library, we use "raw-dylib". This
// crate to link to it. // was added in Rust 1.65 for x86_64/aarch64 and in Rust 1.71 for x86.
// // We don't need MSRV 1.71, as we only use this backend on Rust 1.78 and later.
// TODO(MSRV 1.71): Migrate to linking as raw-dylib directly. #[cfg_attr(
// https://github.com/joboet/rust/blob/5c1c72572479afe98734d5f78fa862abe662c41a/library/std/src/sys/pal/windows/c.rs#L119 target_arch = "x86",
// https://github.com/microsoft/windows-rs/blob/0.60.0/crates/libs/targets/src/lib.rs link(
windows_targets::link!("bcryptprimitives.dll" "system" fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> i32); name = "bcryptprimitives",
kind = "raw-dylib",
import_name_type = "undecorated"
)
)]
#[cfg_attr(
not(target_arch = "x86"),
link(name = "bcryptprimitives", kind = "raw-dylib")
)]
extern "system" {
fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
}
#[allow(clippy::upper_case_acronyms)]
type BOOL = core::ffi::c_int; // MSRV 1.64, similarly OK for this backend.
const TRUE: BOOL = 1;
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let result = unsafe { ProcessPrng(dest.as_mut_ptr().cast::<u8>(), dest.len()) }; let result = unsafe { ProcessPrng(dest.as_mut_ptr().cast::<u8>(), dest.len()) };
// Since Windows 10, calls to the user-mode RNG are guaranteed to never // Since Windows 10, calls to the user-mode RNG are guaranteed to never
@@ -41,6 +56,6 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// return 1 (which is how windows represents TRUE). // return 1 (which is how windows represents TRUE).
// See the bottom of page 6 of the aforementioned Windows RNG // See the bottom of page 6 of the aforementioned Windows RNG
// whitepaper for more information. // whitepaper for more information.
debug_assert!(result == 1); debug_assert!(result == TRUE);
Ok(()) Ok(())
} }

View File

@@ -25,6 +25,7 @@ extern "system" {
type BOOLEAN = u8; type BOOLEAN = u8;
const TRUE: BOOLEAN = 1u8; const TRUE: BOOLEAN = 1u8;
#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Prevent overflow of u32 // Prevent overflow of u32
let chunk_size = usize::try_from(i32::MAX).expect("Windows does not support 16-bit targets"); let chunk_size = usize::try_from(i32::MAX).expect("Windows does not support 16-bit targets");

View File

@@ -1,15 +1,20 @@
#[cfg(feature = "std")] #[cfg(feature = "std")]
extern crate std; extern crate std;
use core::{fmt, num::NonZeroU32}; use core::fmt;
// This private alias mirrors `std::io::RawOsError`: // This private alias mirrors `std::io::RawOsError`:
// https://doc.rust-lang.org/std/io/type.RawOsError.html) // https://doc.rust-lang.org/std/io/type.RawOsError.html)
cfg_if::cfg_if!( cfg_if::cfg_if!(
if #[cfg(target_os = "uefi")] { if #[cfg(target_os = "uefi")] {
// See the UEFI spec for more information:
// https://uefi.org/specs/UEFI/2.10/Apx_D_Status_Codes.html
type RawOsError = usize; type RawOsError = usize;
type NonZeroRawOsError = core::num::NonZeroUsize;
const UEFI_ERROR_FLAG: RawOsError = 1 << (RawOsError::BITS - 1);
} else { } else {
type RawOsError = i32; type RawOsError = i32;
type NonZeroRawOsError = core::num::NonZeroI32;
} }
); );
@@ -19,16 +24,16 @@ cfg_if::cfg_if!(
/// if so, which error code the OS gave the application. If such an error is /// if so, which error code the OS gave the application. If such an error is
/// encountered, please consult with your system documentation. /// encountered, please consult with your system documentation.
/// ///
/// Internally this type is a NonZeroU32, with certain values reserved for
/// certain purposes, see [`Error::INTERNAL_START`] and [`Error::CUSTOM_START`].
///
/// *If this crate's `"std"` Cargo feature is enabled*, then: /// *If this crate's `"std"` Cargo feature is enabled*, then:
/// - [`getrandom::Error`][Error] implements /// - [`getrandom::Error`][Error] implements
/// [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html) /// [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html)
/// - [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html) implements /// - [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html) implements
/// [`From<getrandom::Error>`](https://doc.rust-lang.org/std/convert/trait.From.html). /// [`From<getrandom::Error>`](https://doc.rust-lang.org/std/convert/trait.From.html).
// note: on non-UEFI targets OS errors are represented as negative integers,
// while on UEFI targets OS errors have the highest bit set to 1.
#[derive(Copy, Clone, Eq, PartialEq)] #[derive(Copy, Clone, Eq, PartialEq)]
pub struct Error(NonZeroU32); pub struct Error(NonZeroRawOsError);
impl Error { impl Error {
/// This target/platform is not supported by `getrandom`. /// This target/platform is not supported by `getrandom`.
@@ -38,29 +43,32 @@ impl Error {
/// Encountered an unexpected situation which should not happen in practice. /// Encountered an unexpected situation which should not happen in practice.
pub const UNEXPECTED: Error = Self::new_internal(2); pub const UNEXPECTED: Error = Self::new_internal(2);
/// Codes below this point represent OS Errors (i.e. positive i32 values). /// Internal errors can be in the range of 2^16..2^17
/// Codes at or above this point, but below [`Error::CUSTOM_START`] are const INTERNAL_START: RawOsError = 1 << 16;
/// reserved for use by the `rand` and `getrandom` crates. /// Custom errors can be in the range of 2^17..(2^17 + 2^16)
pub const INTERNAL_START: u32 = 1 << 31; const CUSTOM_START: RawOsError = 1 << 17;
/// Codes at or above this point can be used by users to define their own /// Creates a new instance of an `Error` from a negative error code.
/// custom errors. #[cfg(not(target_os = "uefi"))]
pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30);
/// Creates a new instance of an `Error` from a particular OS error code.
///
/// This method is analogous to [`std::io::Error::from_raw_os_error()`][1],
/// except that it works in `no_std` contexts and `code` will be
/// replaced with `Error::UNEXPECTED` if it isn't in the range
/// `1..Error::INTERNAL_START`. Thus, for the result `r`,
/// `r == Self::UNEXPECTED || r.raw_os_error().unsigned_abs() == code`.
///
/// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.from_raw_os_error
#[allow(dead_code)] #[allow(dead_code)]
pub(super) fn from_os_error(code: u32) -> Self { pub(super) fn from_neg_error_code(code: RawOsError) -> Self {
match NonZeroU32::new(code) { if code < 0 {
Some(code) if code.get() < Self::INTERNAL_START => Self(code), let code = NonZeroRawOsError::new(code).expect("`code` is negative");
_ => Self::UNEXPECTED, Self(code)
} else {
Error::UNEXPECTED
}
}
/// Creates a new instance of an `Error` from an UEFI error code.
#[cfg(target_os = "uefi")]
#[allow(dead_code)]
pub(super) fn from_uefi_code(code: RawOsError) -> Self {
if code & UEFI_ERROR_FLAG != 0 {
let code = NonZeroRawOsError::new(code).expect("The highest bit of `code` is set to 1");
Self(code)
} else {
Self::UNEXPECTED
} }
} }
@@ -79,27 +87,53 @@ impl Error {
#[inline] #[inline]
pub fn raw_os_error(self) -> Option<RawOsError> { pub fn raw_os_error(self) -> Option<RawOsError> {
let code = self.0.get(); let code = self.0.get();
if code >= Self::INTERNAL_START {
return None; // note: in this method we need to cover only backends which rely on
// `Error::{from_error_code, from_errno, from_uefi_code}` methods,
// on all other backends this method always returns `None`.
#[cfg(target_os = "uefi")]
{
if code & UEFI_ERROR_FLAG != 0 {
Some(code)
} else {
None
}
}
#[cfg(not(target_os = "uefi"))]
{
// On most targets `std` expects positive error codes while retrieving error strings:
// - `libc`-based targets use `strerror_r` which expects positive error codes.
// - Hermit relies on the `hermit-abi` crate, which expects positive error codes:
// https://docs.rs/hermit-abi/0.4.0/src/hermit_abi/errno.rs.html#400-532
// - WASIp1 uses the same conventions as `libc`:
// https://github.com/rust-lang/rust/blob/1.85.0/library/std/src/sys/pal/wasi/os.rs#L57-L67
//
// The only exception is Solid, `std` expects negative system error codes, see:
// https://github.com/rust-lang/rust/blob/1.85.0/library/std/src/sys/pal/solid/error.rs#L5-L31
if code >= 0 {
None
} else if cfg!(not(target_os = "solid_asp3")) {
code.checked_neg()
} else {
Some(code)
}
} }
let errno = RawOsError::try_from(code).ok()?;
#[cfg(target_os = "solid_asp3")]
let errno = -errno;
Some(errno)
} }
/// Creates a new instance of an `Error` from a particular custom error code. /// Creates a new instance of an `Error` from a particular custom error code.
pub const fn new_custom(n: u16) -> Error { pub const fn new_custom(n: u16) -> Error {
// SAFETY: code > 0 as CUSTOM_START > 0 and adding n won't overflow a u32. // SAFETY: code > 0 as CUSTOM_START > 0 and adding `n` won't overflow `RawOsError`.
let code = Error::CUSTOM_START + (n as u32); let code = Error::CUSTOM_START + (n as RawOsError);
Error(unsafe { NonZeroU32::new_unchecked(code) }) Error(unsafe { NonZeroRawOsError::new_unchecked(code) })
} }
/// Creates a new instance of an `Error` from a particular internal error code. /// Creates a new instance of an `Error` from a particular internal error code.
pub(crate) const fn new_internal(n: u16) -> Error { pub(crate) const fn new_internal(n: u16) -> Error {
// SAFETY: code > 0 as INTERNAL_START > 0 and adding n won't overflow a u32. // SAFETY: code > 0 as INTERNAL_START > 0 and adding `n` won't overflow `RawOsError`.
let code = Error::INTERNAL_START + (n as u32); let code = Error::INTERNAL_START + (n as RawOsError);
Error(unsafe { NonZeroU32::new_unchecked(code) }) Error(unsafe { NonZeroRawOsError::new_unchecked(code) })
} }
fn internal_desc(&self) -> Option<&'static str> { fn internal_desc(&self) -> Option<&'static str> {
@@ -176,15 +210,3 @@ impl fmt::Display for Error {
} }
} }
} }
#[cfg(test)]
mod tests {
use super::Error;
use core::mem::size_of;
#[test]
fn test_size() {
assert_eq!(size_of::<Error>(), 4);
assert_eq!(size_of::<Result<(), Error>>(), 4);
}
}

View File

@@ -10,6 +10,7 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)] #![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(getrandom_backend = "efi_rng", feature(uefi_std))]
#![deny( #![deny(
clippy::cast_lossless, clippy::cast_lossless,
clippy::cast_possible_truncation, clippy::cast_possible_truncation,

View File

@@ -49,6 +49,7 @@ fn ptr_from_ref<T: ?Sized>(r: &T) -> *const T {
} }
/// Default implementation of `inner_u32` on top of `fill_uninit` /// Default implementation of `inner_u32` on top of `fill_uninit`
#[inline]
pub fn inner_u32() -> Result<u32, Error> { pub fn inner_u32() -> Result<u32, Error> {
let mut res = MaybeUninit::<u32>::uninit(); let mut res = MaybeUninit::<u32>::uninit();
// SAFETY: the created slice has the same size as `res` // SAFETY: the created slice has the same size as `res`
@@ -63,6 +64,7 @@ pub fn inner_u32() -> Result<u32, Error> {
} }
/// Default implementation of `inner_u64` on top of `fill_uninit` /// Default implementation of `inner_u64` on top of `fill_uninit`
#[inline]
pub fn inner_u64() -> Result<u64, Error> { pub fn inner_u64() -> Result<u64, Error> {
let mut res = MaybeUninit::<u64>::uninit(); let mut res = MaybeUninit::<u64>::uninit();
// SAFETY: the created slice has the same size as `res` // SAFETY: the created slice has the same size as `res`

View File

@@ -2,7 +2,7 @@ use crate::Error;
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
cfg_if! { cfg_if! {
if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android"))] { if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android", target_os = "cygwin"))] {
use libc::__errno as errno_location; use libc::__errno as errno_location;
} else if #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "hurd", target_os = "redox", target_os = "dragonfly"))] { } else if #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "hurd", target_os = "redox", target_os = "dragonfly"))] {
use libc::__errno_location as errno_location; use libc::__errno_location as errno_location;
@@ -34,14 +34,16 @@ cfg_if! {
} }
pub(crate) fn last_os_error() -> Error { pub(crate) fn last_os_error() -> Error {
let errno: libc::c_int = unsafe { get_errno() }; // We assume that on all targets which use the `util_libc` module `c_int` is equal to `i32`
let errno: i32 = unsafe { get_errno() };
// c_int-to-u32 conversion is lossless for nonnegative values if they are the same size. if errno > 0 {
const _: () = assert!(core::mem::size_of::<libc::c_int>() == core::mem::size_of::<u32>()); let code = errno
.checked_neg()
match u32::try_from(errno) { .expect("Positive number can be always negated");
Ok(code) if code != 0 => Error::from_os_error(code), Error::from_neg_error_code(code)
_ => Error::ERRNO_NOT_POSITIVE, } else {
Error::ERRNO_NOT_POSITIVE
} }
} }

View File

@@ -1 +1 @@
{"files":{"Cargo.toml":"9eb074df6c05dd3b88b3bd5b68312da8552b116e148d9270ce474840408cf93f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"de412b60535de63bd312ab0df197f72b89d6aaeab166ed090f58a26dcda72bcf","src/error.rs":"f947d858ba95a9a08d16325d163b61fdf0ce40ec95b7fb08cc47c9876de9c8dc","src/lib.rs":"9b82f32a87deae5bd5a0ed36cdab3a195f9419c6befa9f77a682f262b9158722","src/unix.rs":"92c2afb1307e50339817a9d5dd70a2457ab15b87699297b889b4d8652a3a1778","src/wasm.rs":"74db7bd1441b7b4d1b53cd83e23097a2b976faf4d18d3f42f583048d27611d4d","src/windows.rs":"a636019813f2ca2236706e6fe4c88166dddf8aa050555941167ff8e55c848cf1","tests/client-of-myself.rs":"ca09bf398f69df4bac1730999e954dbbc3faf3c6512678c136e0938e7e9cd0ab","tests/client.rs":"5d9b3606356c0fed0c9f5bf372f0fa09f922f93ffe910a1a9a474898d5ec9fa2","tests/helper.rs":"7b8d9eb8484ccf1e656ed235a23f62c2756045e3a6604121aee5493d8a5b1ede","tests/make-as-a-client.rs":"8be1f3fef1e9e65c7904dbaa04364bf0f44e9deab84a2a247a5a94b5cf0df9bc","tests/server.rs":"da15bf12e1df1883f660892b996c9e0d92485aace3f7b50ee70c4a8e6deae8da"},"package":"48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"} {"files":{"Cargo.lock":"c4b876198c51462999d8485d55c13b9adbb8ec8d3139ee22a0b3b779ae848d1d","Cargo.toml":"d6392932a8989572704e9f1214fde950b436987afee156bb3c1710ecc37be518","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"de412b60535de63bd312ab0df197f72b89d6aaeab166ed090f58a26dcda72bcf","src/error.rs":"f947d858ba95a9a08d16325d163b61fdf0ce40ec95b7fb08cc47c9876de9c8dc","src/lib.rs":"9b82f32a87deae5bd5a0ed36cdab3a195f9419c6befa9f77a682f262b9158722","src/unix.rs":"e76e4073040f7576d54f1eaa9beb4a10e1c0ca4602f794de7204491b161676cc","src/wasm.rs":"74db7bd1441b7b4d1b53cd83e23097a2b976faf4d18d3f42f583048d27611d4d","src/windows.rs":"d939574ff187be4fa6bfba4cb9f2cb95541dc8752d0e2915c8b9de90bd833755","tests/client-of-myself.rs":"ca09bf398f69df4bac1730999e954dbbc3faf3c6512678c136e0938e7e9cd0ab","tests/client.rs":"5d9b3606356c0fed0c9f5bf372f0fa09f922f93ffe910a1a9a474898d5ec9fa2","tests/helper.rs":"7b8d9eb8484ccf1e656ed235a23f62c2756045e3a6604121aee5493d8a5b1ede","tests/make-as-a-client.rs":"8be1f3fef1e9e65c7904dbaa04364bf0f44e9deab84a2a247a5a94b5cf0df9bc","tests/server.rs":"da15bf12e1df1883f660892b996c9e0d92485aace3f7b50ee70c4a8e6deae8da"},"package":"38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"}

198
third_party/rust/jobserver/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,198 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "errno"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "fastrand"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
name = "getrandom"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi",
]
[[package]]
name = "jobserver"
version = "0.1.33"
dependencies = [
"getrandom",
"libc",
"nix",
"tempfile",
]
[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "linux-raw-sys"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
[[package]]
name = "nix"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [
"bitflags",
"cfg-if",
"cfg_aliases",
"libc",
]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "rustix"
version = "0.38.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "tempfile"
version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if",
"fastrand",
"rustix",
"windows-sys",
]
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]

View File

@@ -13,8 +13,14 @@
edition = "2021" edition = "2021"
rust-version = "1.63" rust-version = "1.63"
name = "jobserver" name = "jobserver"
version = "0.1.32" version = "0.1.33"
authors = ["Alex Crichton <alex@alexcrichton.com>"] authors = ["Alex Crichton <alex@alexcrichton.com>"]
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = """ description = """
An implementation of the GNU Make jobserver for Rust. An implementation of the GNU Make jobserver for Rust.
""" """
@@ -24,35 +30,43 @@ readme = "README.md"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/jobserver-rs" repository = "https://github.com/rust-lang/jobserver-rs"
[lib]
name = "jobserver"
path = "src/lib.rs"
[[test]] [[test]]
name = "client" name = "client"
path = "tests/client.rs" path = "tests/client.rs"
harness = false harness = false
[[test]]
name = "server"
path = "tests/server.rs"
[[test]] [[test]]
name = "client-of-myself" name = "client-of-myself"
path = "tests/client-of-myself.rs" path = "tests/client-of-myself.rs"
harness = false harness = false
[[test]]
name = "helper"
path = "tests/helper.rs"
[[test]] [[test]]
name = "make-as-a-client" name = "make-as-a-client"
path = "tests/make-as-a-client.rs" path = "tests/make-as-a-client.rs"
harness = false harness = false
[[test]] [[test]]
name = "helper" name = "server"
path = "tests/helper.rs" path = "tests/server.rs"
[dev-dependencies.tempfile] [dev-dependencies.tempfile]
version = "3.10.1" version = "3.10.1"
[target."cfg(unix)".dependencies.libc] [target."cfg(unix)".dependencies.libc]
version = "0.2.87" version = "0.2.171"
[target."cfg(unix)".dev-dependencies.nix] [target."cfg(unix)".dev-dependencies.nix]
version = "0.28.0" version = "0.28.0"
features = ["fs"] features = ["fs"]
[target."cfg(windows)".dependencies.getrandom]
version = "0.3.2"
features = ["std"]

View File

@@ -394,14 +394,7 @@ pub(crate) fn spawn_helper(
let mut err = None; let mut err = None;
USR1_INIT.call_once(|| unsafe { USR1_INIT.call_once(|| unsafe {
let mut new: libc::sigaction = mem::zeroed(); let mut new: libc::sigaction = mem::zeroed();
#[cfg(target_os = "aix")] new.sa_sigaction = sigusr1_handler as usize;
{
new.sa_union.__su_sigaction = sigusr1_handler;
}
#[cfg(not(target_os = "aix"))]
{
new.sa_sigaction = sigusr1_handler as usize;
}
new.sa_flags = libc::SA_SIGINFO as _; new.sa_flags = libc::SA_SIGINFO as _;
if libc::sigaction(libc::SIGUSR1, &new, ptr::null_mut()) != 0 { if libc::sigaction(libc::SIGUSR1, &new, ptr::null_mut()) != 0 {
err = Some(io::Error::last_os_error()); err = Some(io::Error::last_os_error());
@@ -516,7 +509,7 @@ unsafe fn fd_check(fd: c_int, check_pipe: bool) -> Result<(), FromEnvErrorInner>
} }
fn clone_fd_and_set_cloexec(fd: c_int) -> Result<File, FromEnvErrorInner> { fn clone_fd_and_set_cloexec(fd: c_int) -> Result<File, FromEnvErrorInner> {
// Safety: fd is a valid fd dand it remains open until returns // Safety: fd is a valid fd and it remains open until returns
unsafe { BorrowedFd::borrow_raw(fd) } unsafe { BorrowedFd::borrow_raw(fd) }
.try_clone_to_owned() .try_clone_to_owned()
.map(File::from) .map(File::from)

View File

@@ -36,6 +36,7 @@ const WAIT_FAILED: DWORD = 4294967295u32;
const WAIT_OBJECT_0: DWORD = 0u32; const WAIT_OBJECT_0: DWORD = 0u32;
const WAIT_TIMEOUT: DWORD = 258u32; const WAIT_TIMEOUT: DWORD = 258u32;
#[link(name = "kernel32")]
extern "system" { extern "system" {
fn CloseHandle(handle: HANDLE) -> BOOL; fn CloseHandle(handle: HANDLE) -> BOOL;
fn SetEvent(hEvent: HANDLE) -> BOOL; fn SetEvent(hEvent: HANDLE) -> BOOL;
@@ -64,27 +65,6 @@ extern "system" {
) -> HANDLE; ) -> HANDLE;
fn OpenSemaphoreA(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: *const i8) -> HANDLE; fn OpenSemaphoreA(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: *const i8) -> HANDLE;
fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD; fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
#[link_name = "SystemFunction036"]
fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: u32) -> u8;
}
// Note that we ideally would use the `getrandom` crate, but unfortunately
// that causes build issues when this crate is used in rust-lang/rust (see
// rust-lang/rust#65014 for more information). As a result we just inline
// the pretty simple Windows-specific implementation of generating
// randomness.
fn getrandom(dest: &mut [u8]) -> io::Result<()> {
// Prevent overflow of u32
for chunk in dest.chunks_mut(u32::MAX as usize) {
let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr(), chunk.len() as u32) };
if ret == 0 {
return Err(io::Error::new(
io::ErrorKind::Other,
"failed to generate random bytes",
));
}
}
Ok(())
} }
impl Client { impl Client {
@@ -98,9 +78,8 @@ impl Client {
// slot and then immediately acquire it (without ever releaseing it // slot and then immediately acquire it (without ever releaseing it
// back). // back).
for _ in 0..100 { for _ in 0..100 {
let mut bytes = [0; 4]; let bytes = getrandom::u32()?;
getrandom(&mut bytes)?; let mut name = format!("__rust_jobserver_semaphore_{}\0", bytes);
let mut name = format!("__rust_jobserver_semaphore_{}\0", u32::from_ne_bytes(bytes));
unsafe { unsafe {
let create_limit = if limit == 0 { 1 } else { limit }; let create_limit = if limit == 0 { 1 } else { limit };
let r = CreateSemaphoreA( let r = CreateSemaphoreA(

File diff suppressed because one or more lines are too long

12
third_party/rust/wasi/Cargo.lock generated vendored
View File

@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "bitflags" name = "bitflags"
@@ -28,9 +28,8 @@ checksum = "1956f5517128a2b6f23ab2dadf1a976f4f5b27962e7724c2bf3d45e539ec098c"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.13.0+wasi-0.2.0" version = "0.14.2+wasi-0.2.4"
dependencies = [ dependencies = [
"bitflags",
"compiler_builtins", "compiler_builtins",
"rustc-std-workspace-alloc", "rustc-std-workspace-alloc",
"rustc-std-workspace-core", "rustc-std-workspace-core",
@@ -39,6 +38,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rt" name = "wit-bindgen-rt"
version = "0.21.0" version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "026d24a27f6712541fa534f2954bd9e0eb66172f033c2157c0f31d106255c497" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]

View File

@@ -12,8 +12,14 @@
[package] [package]
edition = "2021" edition = "2021"
name = "wasi" name = "wasi"
version = "0.13.0+wasi-0.2.0" version = "0.14.2+wasi-0.2.4"
authors = ["The Cranelift Project Developers"] authors = ["The Cranelift Project Developers"]
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "WASI API bindings for Rust" description = "WASI API bindings for Rust"
documentation = "https://docs.rs/wasi" documentation = "https://docs.rs/wasi"
readme = "README.md" readme = "README.md"
@@ -26,18 +32,51 @@ categories = [
"wasm", "wasm",
] ]
license = "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT" license = "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT"
repository = "https://github.com/bytecodealliance/wasi" repository = "https://github.com/bytecodealliance/wasi-rs"
[features]
default = ["std"]
rustc-dep-of-std = [
"compiler_builtins",
"core",
"rustc-std-workspace-alloc",
]
std = []
[lib]
name = "wasi"
path = "src/lib.rs"
[[example]] [[example]]
name = "cli-command" name = "cli-command"
crate-type = ["cdylib"] crate-type = ["cdylib"]
path = "examples/cli-command.rs"
required-features = ["std"]
[[example]]
name = "cli-command-no_std"
crate-type = ["cdylib"]
path = "examples/cli-command-no_std.rs"
[[example]]
name = "hello-world"
path = "examples/hello-world.rs"
required-features = ["std"]
[[example]]
name = "hello-world-no_std"
path = "examples/hello-world-no_std.rs"
[[example]] [[example]]
name = "http-proxy" name = "http-proxy"
crate-type = ["cdylib"] crate-type = ["cdylib"]
path = "examples/http-proxy.rs"
required-features = ["std"]
[dependencies.bitflags] [[example]]
version = "2.4.2" name = "http-proxy-no_std"
crate-type = ["cdylib"]
path = "examples/http-proxy-no_std.rs"
[dependencies.compiler_builtins] [dependencies.compiler_builtins]
version = "0.1" version = "0.1"
@@ -53,16 +92,5 @@ version = "1.0"
optional = true optional = true
[dependencies.wit-bindgen-rt] [dependencies.wit-bindgen-rt]
version = "0.21.0" version = "0.39.0"
features = ["bitflags"]
[features]
default = ["std"]
rustc-dep-of-std = [
"compiler_builtins",
"core",
"rustc-std-workspace-alloc",
]
std = []
[badges.maintenance]
status = "experimental"

View File

@@ -31,11 +31,10 @@ This crate is procedurally generated from [WIT] files using [`wit-bindgen`].
# Usage # Usage
First you can depend on this crate via `Cargo.toml`: Depending on this crate can be done by adding it to your dependencies:
```toml ```sh
[dependencies] $ cargo add wasi
wasi = "0.12.0"
``` ```
Next you can use the APIs in the root of the module like so: Next you can use the APIs in the root of the module like so:
@@ -47,12 +46,33 @@ fn main() {
} }
``` ```
This crate is intended to target [components] but today you need to go through This crate can currently be used in three main ways.
the intermediate build step of a core WebAssembly module using the `wasm32-wasi`
target: - One is to use it and compile for the [`wasm32-wasip2` target] in Rust 1.82 and later.
This is the simplest approach, as all the tools needed are included in the
Rust tooling, however it doesn't yet support some of the features of the
other approaches.
- Another is to use it and compile using [`cargo component`]. This is essentially
the same as the next option, except that `cargo component` handles most of the
steps for you. `cargo component` also has a number of additional features for
working with dependencies and custom WIT interfaces.
- And the third is to compile for the `wasm32-wasip1` target, and then adapt
the resulting modules into component using `wasm-tools component new`; see
the next section here for details.
[`wasm32-wasip2` target]: https://blog.rust-lang.org/2024/11/26/wasip2-tier-2.html
[`cargo component`]: https://github.com/bytecodealliance/cargo-component
## Building with wasm32-wasip1 and `cargo component new`.
The `wasm32-wasip2` target works with a simple `cargo build --target=wasm32-wasip2`
and doesn't need a lot of documentation here, and `cargo component` has its own
documentation, so here we have some documentation for the `wasm32-wasip1` way.
``` ```
$ cargo build --target wasm32-wasi $ cargo build --target wasm32-wasip1
``` ```
Next you'll want an "adapter" to convert the Rust standard library's usage of Next you'll want an "adapter" to convert the Rust standard library's usage of
@@ -68,7 +88,7 @@ component:
``` ```
$ cargo install wasm-tools $ cargo install wasm-tools
$ wasm-tools component new target/wasm32-wasi/debug/foo.wasm \ $ wasm-tools component new target/wasm32-wasip1/debug/foo.wasm \
--adapt ./wasi_snapshot_preview1.command.wasm \ --adapt ./wasi_snapshot_preview1.command.wasm \
-o component.wasm -o component.wasm
``` ```
@@ -110,19 +130,17 @@ want to support. Rust WebAssembly targets include:
* `wasm32-unknown-unknown` - do not use this crate because this target indicates * `wasm32-unknown-unknown` - do not use this crate because this target indicates
that WASI is not desired. that WASI is not desired.
* `wasm32-wasi` or `wasm32-wasip1` - this target has been present in Rust for * `wasm32-wasip1` - this target has been present in Rust for quite some time and
quite some time and is recently being renamed from `wasm32-wasi` to was previously known as `wasm32-wasi`. For this target you probably want the
`wasm32-wasip1`. The two targets have the same definition, it's just the name 0.11.0 track of this crate.
that's changing. For this target you probably want the 0.11.0 track of this
crate.
* `wasm32-wasip2` - this target is a recent addition to rustc (as of the time of * `wasm32-wasip2` - this target is a recent addition to rustc (as of the time of
this writing it's not merged yet into rustc). This is what the 0.12.0 version this writing it's not merged yet into rustc). This is what the 0.12.0 version
of the crate is intended for. of the crate is intended for.
Note that if you use `wasm32-wasi` or `wasm32-wasip1` it's not necessarily Note that if you use `wasm32-wasip1` it's not necessarily guaranteed you want
guaranteed you want 0.11.0 of this crate. If your users are producing components 0.11.0 of this crate. If your users are producing components then you probably
then you probably want 0.12.0 instead. If you don't know what your users are want 0.12.0 instead. If you don't know what your users are producing then you
producing then you should probably stick with 0.11.0. should probably stick with 0.11.0.
Long story short, it's a bit complicated. We're in a transition period from Long story short, it's a bit complicated. We're in a transition period from
WASIp1 to WASIp2 and things aren't going to be perfect every step of the way, so WASIp1 to WASIp2 and things aren't going to be perfect every step of the way, so
@@ -148,7 +166,7 @@ This project is triple licenced under the Apache 2/ Apache 2 with LLVM exception
- Apache 2/ MIT is used in the rust standard library, and some of this code may be migrated there. - Apache 2/ MIT is used in the rust standard library, and some of this code may be migrated there.
- Some of this code may be used in compiler output, and the Apache 2 with LLVM exceptions licence is useful for this. - Some of this code may be used in compiler output, and the Apache 2 with LLVM exceptions licence is useful for this.
For more details see For more details see
- [Apache 2 Licence](LICENSE-APACHE) - [Apache 2 Licence](LICENSE-APACHE)
- [Apache 2 Licence with LLVM exceptions](LICENSE-Apache-2.0_WITH_LLVM-exception) - [Apache 2 Licence with LLVM exceptions](LICENSE-Apache-2.0_WITH_LLVM-exception)
- [MIT Licence](LICENSE-MIT) - [MIT Licence](LICENSE-MIT)

View File

@@ -5,46 +5,46 @@ set -ex
generate() { generate() {
file="$1" file="$1"
shift shift
wit-bindgen rust wit --out-dir src --std-feature "$@" --rustfmt \ wit-bindgen rust wit --async none --out-dir src --std-feature "$@" --format \
--bitflags-path bitflags \
--runtime-path wit_bindgen_rt --runtime-path wit_bindgen_rt
} }
# Generate the main body of the bindings which includes all imports from the two # Generate the main body of the bindings which includes all imports from the two
# worlds below. # worlds below.
generate src/bindings.rs --type-section-suffix rust-wasi-from-crates-io generate src/bindings.rs --type-section-suffix rust-wasi-from-crates-io \
--generate-all
# Generate bindings for the `wasi:cli/command` world specifically, namely the # Generate bindings for the `wasi:cli/command` world specifically, namely the
# macro `export_command`. # macro `export_command`.
# #
# Note that `--with` is used to point at the previously generated bindings. # Note that `--with` is used to point at the previously generated bindings.
with="wasi:cli/environment@0.2.0=crate::cli::environment" with="wasi:cli/environment@0.2.4=crate::cli::environment"
with="$with,wasi:cli/exit@0.2.0=crate::cli::exit" with="$with,wasi:cli/exit@0.2.4=crate::cli::exit"
with="$with,wasi:cli/stdin@0.2.0=crate::cli::stdin" with="$with,wasi:cli/stdin@0.2.4=crate::cli::stdin"
with="$with,wasi:cli/stdout@0.2.0=crate::cli::stdout" with="$with,wasi:cli/stdout@0.2.4=crate::cli::stdout"
with="$with,wasi:cli/stderr@0.2.0=crate::cli::stderr" with="$with,wasi:cli/stderr@0.2.4=crate::cli::stderr"
with="$with,wasi:cli/terminal-input@0.2.0=crate::cli::terminal_input" with="$with,wasi:cli/terminal-input@0.2.4=crate::cli::terminal_input"
with="$with,wasi:cli/terminal-output@0.2.0=crate::cli::terminal_output" with="$with,wasi:cli/terminal-output@0.2.4=crate::cli::terminal_output"
with="$with,wasi:cli/terminal-stdin@0.2.0=crate::cli::terminal_stdin" with="$with,wasi:cli/terminal-stdin@0.2.4=crate::cli::terminal_stdin"
with="$with,wasi:cli/terminal-stdout@0.2.0=crate::cli::terminal_stdout" with="$with,wasi:cli/terminal-stdout@0.2.4=crate::cli::terminal_stdout"
with="$with,wasi:cli/terminal-stderr@0.2.0=crate::cli::terminal_stderr" with="$with,wasi:cli/terminal-stderr@0.2.4=crate::cli::terminal_stderr"
with="$with,wasi:clocks/monotonic-clock@0.2.0=crate::clocks::monotonic_clock" with="$with,wasi:clocks/monotonic-clock@0.2.4=crate::clocks::monotonic_clock"
with="$with,wasi:clocks/wall-clock@0.2.0=crate::clocks::wall_clock" with="$with,wasi:clocks/wall-clock@0.2.4=crate::clocks::wall_clock"
with="$with,wasi:filesystem/types@0.2.0=crate::filesystem::types" with="$with,wasi:filesystem/types@0.2.4=crate::filesystem::types"
with="$with,wasi:filesystem/preopens@0.2.0=crate::filesystem::preopens" with="$with,wasi:filesystem/preopens@0.2.4=crate::filesystem::preopens"
with="$with,wasi:io/error@0.2.0=crate::io::error" with="$with,wasi:io/error@0.2.4=crate::io::error"
with="$with,wasi:io/poll@0.2.0=crate::io::poll" with="$with,wasi:io/poll@0.2.4=crate::io::poll"
with="$with,wasi:io/streams@0.2.0=crate::io::streams" with="$with,wasi:io/streams@0.2.4=crate::io::streams"
with="$with,wasi:random/random@0.2.0=crate::random::random" with="$with,wasi:random/random@0.2.4=crate::random::random"
with="$with,wasi:random/insecure@0.2.0=crate::random::insecure" with="$with,wasi:random/insecure@0.2.4=crate::random::insecure"
with="$with,wasi:random/insecure-seed@0.2.0=crate::random::insecure_seed" with="$with,wasi:random/insecure-seed@0.2.4=crate::random::insecure_seed"
with="$with,wasi:sockets/network@0.2.0=crate::sockets::network" with="$with,wasi:sockets/network@0.2.4=crate::sockets::network"
with="$with,wasi:sockets/instance-network@0.2.0=crate::sockets::instance_network" with="$with,wasi:sockets/instance-network@0.2.4=crate::sockets::instance_network"
with="$with,wasi:sockets/tcp@0.2.0=crate::sockets::tcp" with="$with,wasi:sockets/tcp@0.2.4=crate::sockets::tcp"
with="$with,wasi:sockets/tcp-create-socket@0.2.0=crate::sockets::tcp_create_socket" with="$with,wasi:sockets/tcp-create-socket@0.2.4=crate::sockets::tcp_create_socket"
with="$with,wasi:sockets/udp@0.2.0=crate::sockets::udp" with="$with,wasi:sockets/udp@0.2.4=crate::sockets::udp"
with="$with,wasi:sockets/udp-create-socket@0.2.0=crate::sockets::udp_create_socket" with="$with,wasi:sockets/udp-create-socket@0.2.4=crate::sockets::udp_create_socket"
with="$with,wasi:sockets/ip-name-lookup@0.2.0=crate::sockets::ip_name_lookup" with="$with,wasi:sockets/ip-name-lookup@0.2.4=crate::sockets::ip_name_lookup"
generate src/command.rs \ generate src/command.rs \
--world wasi:cli/command \ --world wasi:cli/command \
--with "$with" \ --with "$with" \
@@ -54,17 +54,17 @@ generate src/command.rs \
--export-macro-name _export_command --export-macro-name _export_command
# Same as the `command` world, but for the proxy world. # Same as the `command` world, but for the proxy world.
with="wasi:cli/stdin@0.2.0=crate::cli::stdin" with="wasi:cli/stdin@0.2.4=crate::cli::stdin"
with="$with,wasi:cli/stdout@0.2.0=crate::cli::stdout" with="$with,wasi:cli/stdout@0.2.4=crate::cli::stdout"
with="$with,wasi:cli/stderr@0.2.0=crate::cli::stderr" with="$with,wasi:cli/stderr@0.2.4=crate::cli::stderr"
with="$with,wasi:clocks/monotonic-clock@0.2.0=crate::clocks::monotonic_clock" with="$with,wasi:clocks/monotonic-clock@0.2.4=crate::clocks::monotonic_clock"
with="$with,wasi:clocks/wall-clock@0.2.0=crate::clocks::wall_clock" with="$with,wasi:clocks/wall-clock@0.2.4=crate::clocks::wall_clock"
with="$with,wasi:io/error@0.2.0=crate::io::error" with="$with,wasi:io/error@0.2.4=crate::io::error"
with="$with,wasi:io/poll@0.2.0=crate::io::poll" with="$with,wasi:io/poll@0.2.4=crate::io::poll"
with="$with,wasi:io/streams@0.2.0=crate::io::streams" with="$with,wasi:io/streams@0.2.4=crate::io::streams"
with="$with,wasi:random/random@0.2.0=crate::random::random" with="$with,wasi:random/random@0.2.4=crate::random::random"
with="$with,wasi:http/types@0.2.0=crate::http::types" with="$with,wasi:http/types@0.2.4=crate::http::types"
with="$with,wasi:http/outgoing-handler@0.2.0=crate::http::outgoing_handler" with="$with,wasi:http/outgoing-handler@0.2.4=crate::http::outgoing_handler"
generate src/proxy.rs \ generate src/proxy.rs \
--world wasi:http/proxy \ --world wasi:http/proxy \
--with "$with" \ --with "$with" \

View File

@@ -1,2 +0,0 @@
max_width = 100
tab_spaces = 2

28
third_party/rust/wasi/ci/vendor-wit.sh vendored Executable file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Script to re-vendor the WIT files that wasi-rs uses as defined by a
# particular tag in upstream repositories.
#
# This script is executed on CI to ensure that everything is up-to-date.
set -ex
# Space-separated list of wasi proposals that are vendored here along with the
# tag that they're all vendored at.
#
# This assumes that the repositories all have the pattern:
# https://github.com/WebAssembly/wasi-$repo
# and every repository has a tag `v$tag` here. That is currently done as part
# of the WASI release process.
repos="cli clocks filesystem http io random sockets"
tag=0.2.4
dst=wit/deps
rm -rf $dst
mkdir -p $dst
for repo in $repos; do
mkdir $dst/$repo
curl -L https://github.com/WebAssembly/wasi-$repo/archive/refs/tags/v$tag.tar.gz | \
tar xzf - --strip-components=2 -C $dst/$repo wasi-$repo-$tag/wit
rm -rf $dst/$repo/deps*
done

View File

@@ -0,0 +1,11 @@
wasi::cli::command::export!(Example);
struct Example;
impl wasi::exports::cli::run::Guest for Example {
fn run() -> Result<(), ()> {
let stdout = wasi::cli::stdout::get_stdout();
stdout.blocking_write_and_flush(b"Hello, WASI!").unwrap();
Ok(())
}
}

View File

@@ -1,11 +1,14 @@
use std::io::Write as _;
wasi::cli::command::export!(Example); wasi::cli::command::export!(Example);
struct Example; struct Example;
impl wasi::exports::cli::run::Guest for Example { impl wasi::exports::cli::run::Guest for Example {
fn run() -> Result<(), ()> { fn run() -> Result<(), ()> {
let stdout = wasi::cli::stdout::get_stdout(); let mut stdout = wasi::cli::stdout::get_stdout();
stdout.blocking_write_and_flush(b"Hello, WASI!").unwrap(); stdout.write_all(b"Hello, WASI!").unwrap();
stdout.flush().unwrap();
Ok(()) Ok(())
} }
} }

View File

@@ -0,0 +1,4 @@
fn main() {
let stdout = wasi::cli::stdout::get_stdout();
stdout.blocking_write_and_flush(b"Hello, world!\n").unwrap();
}

View File

@@ -1,4 +1,7 @@
use std::io::Write as _;
fn main() { fn main() {
let stdout = wasi::cli::stdout::get_stdout(); let mut stdout = wasi::cli::stdout::get_stdout();
stdout.blocking_write_and_flush(b"Hello, world!\n").unwrap(); stdout.write_all(b"Hello, world!\n").unwrap();
stdout.flush().unwrap();
} }

View File

@@ -0,0 +1,22 @@
use wasi::http::types::{
Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam,
};
wasi::http::proxy::export!(Example);
struct Example;
impl wasi::exports::http::incoming_handler::Guest for Example {
fn handle(_request: IncomingRequest, response_out: ResponseOutparam) {
let resp = OutgoingResponse::new(Fields::new());
let body = resp.body().unwrap();
ResponseOutparam::set(response_out, Ok(resp));
let out = body.write().unwrap();
out.blocking_write_and_flush(b"Hello, WASI!").unwrap();
drop(out);
OutgoingBody::finish(body, None).unwrap();
}
}

View File

@@ -1,3 +1,5 @@
use std::io::Write as _;
use wasi::http::types::{ use wasi::http::types::{
Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam, Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam,
}; };
@@ -13,8 +15,9 @@ impl wasi::exports::http::incoming_handler::Guest for Example {
ResponseOutparam::set(response_out, Ok(resp)); ResponseOutparam::set(response_out, Ok(resp));
let out = body.write().unwrap(); let mut out = body.write().unwrap();
out.blocking_write_and_flush(b"Hello, WASI!").unwrap(); out.write_all(b"Hello, WASI!").unwrap();
out.flush().unwrap();
drop(out); drop(out);
OutgoingBody::finish(body, None).unwrap(); OutgoingBody::finish(body, None).unwrap();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

8
third_party/rust/wasi/src/ext/mod.rs vendored Normal file
View File

@@ -0,0 +1,8 @@
#[cfg(feature = "std")]
mod std;
impl core::fmt::Display for crate::io::error::Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&self.to_debug_string())
}
}

69
third_party/rust/wasi/src/ext/std.rs vendored Normal file
View File

@@ -0,0 +1,69 @@
use std::error::Error;
use std::io;
use std::num::NonZeroU64;
use crate::io::streams::StreamError;
impl Error for crate::io::error::Error {}
impl io::Read for crate::io::streams::InputStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let n = buf
.len()
.try_into()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
match self.blocking_read(n) {
Ok(chunk) => {
let n = chunk.len();
if n > buf.len() {
return Err(io::Error::new(
io::ErrorKind::Other,
"more bytes read than requested",
));
}
buf[..n].copy_from_slice(&chunk);
Ok(n)
}
Err(StreamError::Closed) => Ok(0),
Err(StreamError::LastOperationFailed(e)) => {
Err(io::Error::new(io::ErrorKind::Other, e.to_debug_string()))
}
}
}
}
impl io::Write for crate::io::streams::OutputStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let n = loop {
match self.check_write().map(NonZeroU64::new) {
Ok(Some(n)) => {
break n;
}
Ok(None) => {
self.subscribe().block();
}
Err(StreamError::Closed) => return Ok(0),
Err(StreamError::LastOperationFailed(e)) => {
return Err(io::Error::new(io::ErrorKind::Other, e.to_debug_string()))
}
};
};
let n = n
.get()
.try_into()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let n = buf.len().min(n);
crate::io::streams::OutputStream::write(self, &buf[..n]).map_err(|e| match e {
StreamError::Closed => io::ErrorKind::UnexpectedEof.into(),
StreamError::LastOperationFailed(e) => {
io::Error::new(io::ErrorKind::Other, e.to_debug_string())
}
})?;
Ok(n)
}
fn flush(&mut self) -> io::Result<()> {
self.blocking_flush()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
}

View File

@@ -127,14 +127,13 @@
//! //!
//! This crate is intended to be easiest to use with a future //! This crate is intended to be easiest to use with a future
//! `wasm32-wasip2` target added to the Rust compiler. In the meantime //! `wasm32-wasip2` target added to the Rust compiler. In the meantime
//! it's recommended to use the `wasm32-wasi` target (soon to be renamed to //! it's recommended to use the `wasm32-wasip1` target instead:
//! `wasm32-wasip1`) instead:
//! //!
//! ```sh //! ```sh
//! $ cargo build --target wasm32-wasi //! $ cargo build --target wasm32-wasip1
//! ``` //! ```
//! //!
//! Note that the output of the `wasm32-wasi` target is a core wasm module, not //! Note that the output of the `wasm32-wasip1` target is a core wasm module, not
//! a component, so to turn it into a component you can use the [`wasm-tools`] //! a component, so to turn it into a component you can use the [`wasm-tools`]
//! CLI in combination with an "adapter module" for the `wasi_snapshot_preview1` //! CLI in combination with an "adapter module" for the `wasi_snapshot_preview1`
//! APIs that the Rust standard library uses (example adapters can be found on //! APIs that the Rust standard library uses (example adapters can be found on
@@ -142,7 +141,7 @@
//! [`wasi_snapshot_preview1.command.wasm`] for example) //! [`wasi_snapshot_preview1.command.wasm`] for example)
//! //!
//! ```sh //! ```sh
//! $ wasm-tools component new ./target/wasm32-wasi/debug/my-app.wasm \ //! $ wasm-tools component new ./target/wasm32-wasip1/debug/my-app.wasm \
//! --adapt ./wasi_snapshot_preview1.command.wasm \ //! --adapt ./wasi_snapshot_preview1.command.wasm \
//! -o my-component.wasm //! -o my-component.wasm
//! ``` //! ```
@@ -179,6 +178,8 @@
#[cfg(feature = "std")] #[cfg(feature = "std")]
extern crate std; extern crate std;
pub mod ext;
// These modules are all auto-generated by `./ci/regenerate.sh` // These modules are all auto-generated by `./ci/regenerate.sh`
mod bindings; mod bindings;
#[allow(unused_imports)] #[allow(unused_imports)]
@@ -219,16 +220,17 @@ pub mod cli {
/// wasi::cli::command::export!(MyCliRunner); /// wasi::cli::command::export!(MyCliRunner);
/// ``` /// ```
/// ///
/// ## Compatibility with `wasm32-wasi` targets /// ## Compatibility with `wasm32-wasip1` targets
/// ///
/// This macro is not compatible with `wasm32-wasi` `bin` targets which /// This macro is not compatible with `wasm32-wasip1` `bin` targets
/// instead use a `fn main()` with the /// which instead use a `fn main()` with the
/// `wasi_snapshot_preview1.command.wasm` adapter. This macro _can_ be /// `wasi_snapshot_preview1.command.wasm` adapter. This macro _can_ be
/// used with the `reactor` or `proxy` adapters. /// used with the `reactor` or `proxy` adapters.
/// ///
/// <!-- /// <!--
/// The marker above hides the generated documentation by wit-bindgen for this /// The marker above hides the generated documentation by wit-bindgen for this
/// macro. /// macro.
/// -->
#[doc(inline)] #[doc(inline)]
pub use crate::command::_export_command as export; pub use crate::command::_export_command as export;
} }
@@ -264,6 +266,7 @@ pub mod http {
/// <!-- /// <!--
/// The marker above hides the generated documentation by wit-bindgen /// The marker above hides the generated documentation by wit-bindgen
/// for this macro. /// for this macro.
/// -->
#[doc(inline)] #[doc(inline)]
pub use crate::proxy::_export_proxy as export; pub use crate::proxy::_export_proxy as export;
} }

View File

@@ -1,53 +1,57 @@
// Generated by `wit-bindgen` 0.21.0. DO NOT EDIT! // Generated by `wit-bindgen` 0.39.0. DO NOT EDIT!
// Options used: // Options used:
// * std_feature // * std_feature
// * with "wasi:cli/stdin@0.2.0" = "crate::cli::stdin" // * runtime_path: "wit_bindgen_rt"
// * with "wasi:cli/stdout@0.2.0" = "crate::cli::stdout" // * with "wasi:cli/stdin@0.2.4" = "crate::cli::stdin"
// * with "wasi:cli/stderr@0.2.0" = "crate::cli::stderr" // * with "wasi:cli/stdout@0.2.4" = "crate::cli::stdout"
// * with "wasi:clocks/monotonic-clock@0.2.0" = "crate::clocks::monotonic_clock" // * with "wasi:cli/stderr@0.2.4" = "crate::cli::stderr"
// * with "wasi:clocks/wall-clock@0.2.0" = "crate::clocks::wall_clock" // * with "wasi:clocks/monotonic-clock@0.2.4" = "crate::clocks::monotonic_clock"
// * with "wasi:io/error@0.2.0" = "crate::io::error" // * with "wasi:clocks/wall-clock@0.2.4" = "crate::clocks::wall_clock"
// * with "wasi:io/poll@0.2.0" = "crate::io::poll" // * with "wasi:io/error@0.2.4" = "crate::io::error"
// * with "wasi:io/streams@0.2.0" = "crate::io::streams" // * with "wasi:io/poll@0.2.4" = "crate::io::poll"
// * with "wasi:random/random@0.2.0" = "crate::random::random" // * with "wasi:io/streams@0.2.4" = "crate::io::streams"
// * with "wasi:http/types@0.2.0" = "crate::http::types" // * with "wasi:random/random@0.2.4" = "crate::random::random"
// * with "wasi:http/outgoing-handler@0.2.0" = "crate::http::outgoing_handler" // * with "wasi:http/types@0.2.4" = "crate::http::types"
// * with "wasi:http/outgoing-handler@0.2.4" = "crate::http::outgoing_handler"
// * type_section_suffix: "rust-wasi-from-crates-io-proxy-world"
// * default-bindings-module: "wasi" // * default-bindings-module: "wasi"
// * export-macro-name: _export_proxy // * export-macro-name: _export_proxy
// * pub-export-macro // * pub-export-macro
use crate::cli::stderr as __with_name5; use crate::io::poll as __with_name0;
use crate::cli::stdin as __with_name6; use crate::clocks::monotonic_clock as __with_name1;
use crate::cli::stdout as __with_name4; use crate::clocks::wall_clock as __with_name2;
use crate::clocks::monotonic_clock as __with_name7; use crate::random::random as __with_name3;
use crate::clocks::wall_clock as __with_name10; use crate::io::error as __with_name4;
use crate::http::outgoing_handler as __with_name9; use crate::io::streams as __with_name5;
use crate::http::types as __with_name8; use crate::cli::stdout as __with_name6;
use crate::io::error as __with_name1; use crate::cli::stderr as __with_name7;
use crate::io::poll as __with_name2; use crate::cli::stdin as __with_name8;
use crate::io::streams as __with_name3; use crate::http::types as __with_name9;
use crate::random::random as __with_name0; use crate::http::outgoing_handler as __with_name10;
#[rustfmt::skip]
#[allow(dead_code, clippy::all)]
pub mod exports { pub mod exports {
pub mod wasi { pub mod wasi {
pub mod http { pub mod http {
#[allow(clippy::all)] /// This interface defines a handler of incoming HTTP Requests. It should
/// be exported by components which can respond to HTTP Requests.
#[allow(dead_code, unused_imports, clippy::all)]
pub mod incoming_handler { pub mod incoming_handler {
#[used] #[used]
#[doc(hidden)] #[doc(hidden)]
#[cfg(target_arch = "wasm32")] static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_custom_section_describing_imports;
static __FORCE_SECTION_REF: fn() = use super::super::super::super::_rt;
super::super::super::super::__link_custom_section_describing_imports; pub type IncomingRequest = super::super::super::super::__with_name9::IncomingRequest;
pub type IncomingRequest = pub type ResponseOutparam = super::super::super::super::__with_name9::ResponseOutparam;
super::super::super::super::__with_name8::IncomingRequest;
pub type ResponseOutparam =
super::super::super::super::__with_name8::ResponseOutparam;
#[doc(hidden)] #[doc(hidden)]
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub unsafe fn _export_handle_cabi<T: Guest>(arg0: i32, arg1: i32) { pub unsafe fn _export_handle_cabi<T: Guest>(arg0: i32, arg1: i32) {
#[cfg(target_arch = "wasm32")] _rt::run_ctors_once();
T::handle( T::handle(
super::super::super::super::__with_name8::IncomingRequest::from_handle( super::super::super::super::__with_name9::IncomingRequest::from_handle(
arg0 as u32, arg0 as u32,
), ),
super::super::super::super::__with_name8::ResponseOutparam::from_handle( super::super::super::super::__with_name9::ResponseOutparam::from_handle(
arg1 as u32, arg1 as u32,
), ),
); );
@@ -63,28 +67,37 @@ pub mod exports {
/// The implementor of this function must write a response to the /// The implementor of this function must write a response to the
/// `response-outparam` before returning, or else the caller will respond /// `response-outparam` before returning, or else the caller will respond
/// with an error on its behalf. /// with an error on its behalf.
fn handle(request: IncomingRequest, response_out: ResponseOutparam); fn handle(
request: IncomingRequest,
response_out: ResponseOutparam,
) -> ();
} }
#[doc(hidden)] #[doc(hidden)]
#[macro_export] #[macro_export]
macro_rules! __export_wasi_http_incoming_handler_0_2_0_cabi{ macro_rules! __export_wasi_http_incoming_handler_0_2_4_cabi {
($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { ($ty:ident with_types_in $($path_to_types:tt)*) => {
const _ : () = { #[unsafe (export_name =
#[export_name = "wasi:http/incoming-handler@0.2.0#handle"] "wasi:http/incoming-handler@0.2.4#handle")] unsafe extern "C" fn
unsafe extern "C" fn export_handle(arg0: i32,arg1: i32,) { export_handle(arg0 : i32, arg1 : i32,) { $($path_to_types)*::
$($path_to_types)*::_export_handle_cabi::<$ty>(arg0, arg1) _export_handle_cabi::<$ty > (arg0, arg1) } };
} };
};); }
}
#[doc(hidden)] #[doc(hidden)]
pub use __export_wasi_http_incoming_handler_0_2_0_cabi; pub use __export_wasi_http_incoming_handler_0_2_4_cabi;
} }
} }
} }
} }
#[rustfmt::skip]
/// Generates `#[no_mangle]` functions to export the specified type as the mod _rt {
/// root implementation of all generated traits. #![allow(dead_code, clippy::all)]
#[cfg(target_arch = "wasm32")]
pub fn run_ctors_once() {
wit_bindgen_rt::run_ctors_once();
}
}
/// Generates `#[unsafe(no_mangle)]` functions to export the specified type as
/// the root implementation of all generated traits.
/// ///
/// For more information see the documentation of `wit_bindgen::generate!`. /// For more information see the documentation of `wit_bindgen::generate!`.
/// ///
@@ -103,59 +116,64 @@ pub mod exports {
#[doc(hidden)] #[doc(hidden)]
#[macro_export] #[macro_export]
macro_rules! __export_proxy_impl { macro_rules! __export_proxy_impl {
($ty:ident) => (wasi::_export_proxy!($ty with_types_in wasi);); ($ty:ident) => {
($ty:ident with_types_in $($path_to_types_root:tt)*) => ( wasi::_export_proxy!($ty with_types_in wasi);
$($path_to_types_root)*::exports::wasi::http::incoming_handler::__export_wasi_http_incoming_handler_0_2_0_cabi!($ty with_types_in $($path_to_types_root)*::exports::wasi::http::incoming_handler); };
const _: () = { ($ty:ident with_types_in $($path_to_types_root:tt)*) => {
$($path_to_types_root)*::
#[cfg(target_arch = "wasm32")] exports::wasi::http::incoming_handler::__export_wasi_http_incoming_handler_0_2_4_cabi!($ty
#[link_section = "component-type:wit-bindgen:0.21.0:proxy:imports and exportsrust-wasi-from-crates-io-proxy-world"] with_types_in $($path_to_types_root)*:: exports::wasi::http::incoming_handler);
#[doc(hidden)] const _ : () = { #[cfg(target_arch = "wasm32")] #[unsafe (link_section =
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 7024] = *b"\ "component-type:wit-bindgen:0.39.0:wasi:http@0.2.4:proxy:imports and exportsrust-wasi-from-crates-io-proxy-world")]
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xf45\x01A\x02\x01A#\x01\ #[doc(hidden)] #[allow(clippy::octal_escapes)] pub static
B\x05\x01p}\x01@\x01\x03lenw\0\0\x04\0\x10get-random-bytes\x01\x01\x01@\0\0w\x04\ __WIT_BINDGEN_COMPONENT_TYPE : [u8; 7040] = *
\0\x0eget-random-u64\x01\x02\x03\x01\x18wasi:random/random@0.2.0\x05\0\x01B\x04\x04\ b"\
\0\x05error\x03\x01\x01h\0\x01@\x01\x04self\x01\0s\x04\0\x1d[method]error.to-deb\ \0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\x846\x01A\x02\x01A#\x01\
ug-string\x01\x02\x03\x01\x13wasi:io/error@0.2.0\x05\x01\x01B\x0a\x04\0\x08polla\ B\x0a\x04\0\x08pollable\x03\x01\x01h\0\x01@\x01\x04self\x01\0\x7f\x04\0\x16[meth\
ble\x03\x01\x01h\0\x01@\x01\x04self\x01\0\x7f\x04\0\x16[method]pollable.ready\x01\ od]pollable.ready\x01\x02\x01@\x01\x04self\x01\x01\0\x04\0\x16[method]pollable.b\
\x02\x01@\x01\x04self\x01\x01\0\x04\0\x16[method]pollable.block\x01\x03\x01p\x01\ lock\x01\x03\x01p\x01\x01py\x01@\x01\x02in\x04\0\x05\x04\0\x04poll\x01\x06\x03\0\
\x01py\x01@\x01\x02in\x04\0\x05\x04\0\x04poll\x01\x06\x03\x01\x12wasi:io/poll@0.\ \x12wasi:io/poll@0.2.4\x05\0\x02\x03\0\0\x08pollable\x01B\x0f\x02\x03\x02\x01\x01\
2.0\x05\x02\x02\x03\0\x01\x05error\x02\x03\0\x02\x08pollable\x01B(\x02\x03\x02\x01\ \x04\0\x08pollable\x03\0\0\x01w\x04\0\x07instant\x03\0\x02\x01w\x04\0\x08duratio\
\x03\x04\0\x05error\x03\0\0\x02\x03\x02\x01\x04\x04\0\x08pollable\x03\0\x02\x01i\ n\x03\0\x04\x01@\0\0\x03\x04\0\x03now\x01\x06\x01@\0\0\x05\x04\0\x0aresolution\x01\
\x01\x01q\x02\x15last-operation-failed\x01\x04\0\x06closed\0\0\x04\0\x0cstream-e\ \x07\x01i\x01\x01@\x01\x04when\x03\0\x08\x04\0\x11subscribe-instant\x01\x09\x01@\
rror\x03\0\x05\x04\0\x0cinput-stream\x03\x01\x04\0\x0doutput-stream\x03\x01\x01h\ \x01\x04when\x05\0\x08\x04\0\x12subscribe-duration\x01\x0a\x03\0!wasi:clocks/mon\
\x07\x01p}\x01j\x01\x0a\x01\x06\x01@\x02\x04self\x09\x03lenw\0\x0b\x04\0\x19[met\ otonic-clock@0.2.4\x05\x02\x01B\x05\x01r\x02\x07secondsw\x0bnanosecondsy\x04\0\x08\
hod]input-stream.read\x01\x0c\x04\0\"[method]input-stream.blocking-read\x01\x0c\x01\ datetime\x03\0\0\x01@\0\0\x01\x04\0\x03now\x01\x02\x04\0\x0aresolution\x01\x02\x03\
j\x01w\x01\x06\x01@\x02\x04self\x09\x03lenw\0\x0d\x04\0\x19[method]input-stream.\ \0\x1cwasi:clocks/wall-clock@0.2.4\x05\x03\x01B\x05\x01p}\x01@\x01\x03lenw\0\0\x04\
skip\x01\x0e\x04\0\"[method]input-stream.blocking-skip\x01\x0e\x01i\x03\x01@\x01\ \0\x10get-random-bytes\x01\x01\x01@\0\0w\x04\0\x0eget-random-u64\x01\x02\x03\0\x18\
\x04self\x09\0\x0f\x04\0\x1e[method]input-stream.subscribe\x01\x10\x01h\x08\x01@\ wasi:random/random@0.2.4\x05\x04\x01B\x04\x04\0\x05error\x03\x01\x01h\0\x01@\x01\
\x01\x04self\x11\0\x0d\x04\0![method]output-stream.check-write\x01\x12\x01j\0\x01\ \x04self\x01\0s\x04\0\x1d[method]error.to-debug-string\x01\x02\x03\0\x13wasi:io/\
\x06\x01@\x02\x04self\x11\x08contents\x0a\0\x13\x04\0\x1b[method]output-stream.w\ error@0.2.4\x05\x05\x02\x03\0\x04\x05error\x01B(\x02\x03\x02\x01\x06\x04\0\x05er\
rite\x01\x14\x04\0.[method]output-stream.blocking-write-and-flush\x01\x14\x01@\x01\ ror\x03\0\0\x02\x03\x02\x01\x01\x04\0\x08pollable\x03\0\x02\x01i\x01\x01q\x02\x15\
\x04self\x11\0\x13\x04\0\x1b[method]output-stream.flush\x01\x15\x04\0$[method]ou\ last-operation-failed\x01\x04\0\x06closed\0\0\x04\0\x0cstream-error\x03\0\x05\x04\
tput-stream.blocking-flush\x01\x15\x01@\x01\x04self\x11\0\x0f\x04\0\x1f[method]o\ \0\x0cinput-stream\x03\x01\x04\0\x0doutput-stream\x03\x01\x01h\x07\x01p}\x01j\x01\
utput-stream.subscribe\x01\x16\x01@\x02\x04self\x11\x03lenw\0\x13\x04\0\"[method\ \x0a\x01\x06\x01@\x02\x04self\x09\x03lenw\0\x0b\x04\0\x19[method]input-stream.re\
]output-stream.write-zeroes\x01\x17\x04\05[method]output-stream.blocking-write-z\ ad\x01\x0c\x04\0\"[method]input-stream.blocking-read\x01\x0c\x01j\x01w\x01\x06\x01\
eroes-and-flush\x01\x17\x01@\x03\x04self\x11\x03src\x09\x03lenw\0\x0d\x04\0\x1c[\ @\x02\x04self\x09\x03lenw\0\x0d\x04\0\x19[method]input-stream.skip\x01\x0e\x04\0\
method]output-stream.splice\x01\x18\x04\0%[method]output-stream.blocking-splice\x01\ \"[method]input-stream.blocking-skip\x01\x0e\x01i\x03\x01@\x01\x04self\x09\0\x0f\
\x18\x03\x01\x15wasi:io/streams@0.2.0\x05\x05\x02\x03\0\x03\x0doutput-stream\x01\ \x04\0\x1e[method]input-stream.subscribe\x01\x10\x01h\x08\x01@\x01\x04self\x11\0\
B\x05\x02\x03\x02\x01\x06\x04\0\x0doutput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\ \x0d\x04\0![method]output-stream.check-write\x01\x12\x01j\0\x01\x06\x01@\x02\x04\
\0\x0aget-stdout\x01\x03\x03\x01\x15wasi:cli/stdout@0.2.0\x05\x07\x01B\x05\x02\x03\ self\x11\x08contents\x0a\0\x13\x04\0\x1b[method]output-stream.write\x01\x14\x04\0\
\x02\x01\x06\x04\0\x0doutput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\0\x0aget-s\ .[method]output-stream.blocking-write-and-flush\x01\x14\x01@\x01\x04self\x11\0\x13\
tderr\x01\x03\x03\x01\x15wasi:cli/stderr@0.2.0\x05\x08\x02\x03\0\x03\x0cinput-st\ \x04\0\x1b[method]output-stream.flush\x01\x15\x04\0$[method]output-stream.blocki\
ream\x01B\x05\x02\x03\x02\x01\x09\x04\0\x0cinput-stream\x03\0\0\x01i\x01\x01@\0\0\ ng-flush\x01\x15\x01@\x01\x04self\x11\0\x0f\x04\0\x1f[method]output-stream.subsc\
\x02\x04\0\x09get-stdin\x01\x03\x03\x01\x14wasi:cli/stdin@0.2.0\x05\x0a\x01B\x0f\ ribe\x01\x16\x01@\x02\x04self\x11\x03lenw\0\x13\x04\0\"[method]output-stream.wri\
\x02\x03\x02\x01\x04\x04\0\x08pollable\x03\0\0\x01w\x04\0\x07instant\x03\0\x02\x01\ te-zeroes\x01\x17\x04\05[method]output-stream.blocking-write-zeroes-and-flush\x01\
w\x04\0\x08duration\x03\0\x04\x01@\0\0\x03\x04\0\x03now\x01\x06\x01@\0\0\x05\x04\ \x17\x01@\x03\x04self\x11\x03src\x09\x03lenw\0\x0d\x04\0\x1c[method]output-strea\
\0\x0aresolution\x01\x07\x01i\x01\x01@\x01\x04when\x03\0\x08\x04\0\x11subscribe-\ m.splice\x01\x18\x04\0%[method]output-stream.blocking-splice\x01\x18\x03\0\x15wa\
instant\x01\x09\x01@\x01\x04when\x05\0\x08\x04\0\x12subscribe-duration\x01\x0a\x03\ si:io/streams@0.2.4\x05\x07\x02\x03\0\x05\x0doutput-stream\x01B\x05\x02\x03\x02\x01\
\x01!wasi:clocks/monotonic-clock@0.2.0\x05\x0b\x02\x03\0\x07\x08duration\x01B\xc0\ \x08\x04\0\x0doutput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\0\x0aget-stdout\x01\
\x01\x02\x03\x02\x01\x0c\x04\0\x08duration\x03\0\0\x02\x03\x02\x01\x09\x04\0\x0c\ \x03\x03\0\x15wasi:cli/stdout@0.2.4\x05\x09\x01B\x05\x02\x03\x02\x01\x08\x04\0\x0d\
input-stream\x03\0\x02\x02\x03\x02\x01\x06\x04\0\x0doutput-stream\x03\0\x04\x02\x03\ output-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\0\x0aget-stderr\x01\x03\x03\0\x15\
\x02\x01\x03\x04\0\x08io-error\x03\0\x06\x02\x03\x02\x01\x04\x04\0\x08pollable\x03\ wasi:cli/stderr@0.2.4\x05\x0a\x02\x03\0\x05\x0cinput-stream\x01B\x05\x02\x03\x02\
\0\x08\x01q\x0a\x03get\0\0\x04head\0\0\x04post\0\0\x03put\0\0\x06delete\0\0\x07c\ \x01\x0b\x04\0\x0cinput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\0\x09get-stdin\x01\
onnect\0\0\x07options\0\0\x05trace\0\0\x05patch\0\0\x05other\x01s\0\x04\0\x06met\ \x03\x03\0\x14wasi:cli/stdin@0.2.4\x05\x0c\x02\x03\0\x01\x08duration\x01B\xc1\x01\
hod\x03\0\x0a\x01q\x03\x04HTTP\0\0\x05HTTPS\0\0\x05other\x01s\0\x04\0\x06scheme\x03\ \x02\x03\x02\x01\x0d\x04\0\x08duration\x03\0\0\x02\x03\x02\x01\x0b\x04\0\x0cinpu\
t-stream\x03\0\x02\x02\x03\x02\x01\x08\x04\0\x0doutput-stream\x03\0\x04\x02\x03\x02\
\x01\x06\x04\0\x08io-error\x03\0\x06\x02\x03\x02\x01\x01\x04\0\x08pollable\x03\0\
\x08\x01q\x0a\x03get\0\0\x04head\0\0\x04post\0\0\x03put\0\0\x06delete\0\0\x07con\
nect\0\0\x07options\0\0\x05trace\0\0\x05patch\0\0\x05other\x01s\0\x04\0\x06metho\
d\x03\0\x0a\x01q\x03\x04HTTP\0\0\x05HTTPS\0\0\x05other\x01s\0\x04\0\x06scheme\x03\
\0\x0c\x01ks\x01k{\x01r\x02\x05rcode\x0e\x09info-code\x0f\x04\0\x11DNS-error-pay\ \0\x0c\x01ks\x01k{\x01r\x02\x05rcode\x0e\x09info-code\x0f\x04\0\x11DNS-error-pay\
load\x03\0\x10\x01k}\x01r\x02\x08alert-id\x12\x0dalert-message\x0e\x04\0\x1aTLS-\ load\x03\0\x10\x01k}\x01r\x02\x08alert-id\x12\x0dalert-message\x0e\x04\0\x1aTLS-\
alert-received-payload\x03\0\x13\x01ky\x01r\x02\x0afield-name\x0e\x0afield-size\x15\ alert-received-payload\x03\0\x13\x01ky\x01r\x02\x0afield-name\x0e\x0afield-size\x15\
@@ -177,137 +195,138 @@ TP-response-header-section-size\x01\x15\0\x19HTTP-response-header-size\x01\x17\0
P-upgrade-failed\0\0\x13HTTP-protocol-error\0\0\x0dloop-detected\0\0\x13configur\ P-upgrade-failed\0\0\x13HTTP-protocol-error\0\0\x0dloop-detected\0\0\x13configur\
ation-error\0\0\x0einternal-error\x01\x0e\0\x04\0\x0aerror-code\x03\0\x1a\x01q\x03\ ation-error\0\0\x0einternal-error\x01\x0e\0\x04\0\x0aerror-code\x03\0\x1a\x01q\x03\
\x0einvalid-syntax\0\0\x09forbidden\0\0\x09immutable\0\0\x04\0\x0cheader-error\x03\ \x0einvalid-syntax\0\0\x09forbidden\0\0\x09immutable\0\0\x04\0\x0cheader-error\x03\
\0\x1c\x01s\x04\0\x09field-key\x03\0\x1e\x01p}\x04\0\x0bfield-value\x03\0\x20\x04\ \0\x1c\x01s\x04\0\x09field-key\x03\0\x1e\x04\0\x0afield-name\x03\0\x1f\x01p}\x04\
\0\x06fields\x03\x01\x04\0\x07headers\x03\0\"\x04\0\x08trailers\x03\0\"\x04\0\x10\ \0\x0bfield-value\x03\0!\x04\0\x06fields\x03\x01\x04\0\x07headers\x03\0#\x04\0\x08\
incoming-request\x03\x01\x04\0\x10outgoing-request\x03\x01\x04\0\x0frequest-opti\ trailers\x03\0#\x04\0\x10incoming-request\x03\x01\x04\0\x10outgoing-request\x03\x01\
ons\x03\x01\x04\0\x11response-outparam\x03\x01\x01{\x04\0\x0bstatus-code\x03\0)\x04\ \x04\0\x0frequest-options\x03\x01\x04\0\x11response-outparam\x03\x01\x01{\x04\0\x0b\
\0\x11incoming-response\x03\x01\x04\0\x0dincoming-body\x03\x01\x04\0\x0ffuture-t\ status-code\x03\0*\x04\0\x11incoming-response\x03\x01\x04\0\x0dincoming-body\x03\
railers\x03\x01\x04\0\x11outgoing-response\x03\x01\x04\0\x0doutgoing-body\x03\x01\ \x01\x04\0\x0ffuture-trailers\x03\x01\x04\0\x11outgoing-response\x03\x01\x04\0\x0d\
\x04\0\x18future-incoming-response\x03\x01\x01i\"\x01@\0\01\x04\0\x13[constructo\ outgoing-body\x03\x01\x04\0\x18future-incoming-response\x03\x01\x01i#\x01@\0\02\x04\
r]fields\x012\x01o\x02\x1f!\x01p3\x01j\x011\x01\x1d\x01@\x01\x07entries4\05\x04\0\ \0\x13[constructor]fields\x013\x01o\x02\x20\"\x01p4\x01j\x012\x01\x1d\x01@\x01\x07\
\x18[static]fields.from-list\x016\x01h\"\x01p!\x01@\x02\x04self7\x04name\x1f\08\x04\ entries5\06\x04\0\x18[static]fields.from-list\x017\x01h#\x01p\"\x01@\x02\x04self\
\0\x12[method]fields.get\x019\x01@\x02\x04self7\x04name\x1f\0\x7f\x04\0\x12[meth\ 8\x04name\x20\09\x04\0\x12[method]fields.get\x01:\x01@\x02\x04self8\x04name\x20\0\
od]fields.has\x01:\x01j\0\x01\x1d\x01@\x03\x04self7\x04name\x1f\x05value8\0;\x04\ \x7f\x04\0\x12[method]fields.has\x01;\x01j\0\x01\x1d\x01@\x03\x04self8\x04name\x20\
\0\x12[method]fields.set\x01<\x01@\x02\x04self7\x04name\x1f\0;\x04\0\x15[method]\ \x05value9\0<\x04\0\x12[method]fields.set\x01=\x01@\x02\x04self8\x04name\x20\0<\x04\
fields.delete\x01=\x01@\x03\x04self7\x04name\x1f\x05value!\0;\x04\0\x15[method]f\ \0\x15[method]fields.delete\x01>\x01@\x03\x04self8\x04name\x20\x05value\"\0<\x04\
ields.append\x01>\x01@\x01\x04self7\04\x04\0\x16[method]fields.entries\x01?\x01@\ \0\x15[method]fields.append\x01?\x01@\x01\x04self8\05\x04\0\x16[method]fields.en\
\x01\x04self7\01\x04\0\x14[method]fields.clone\x01@\x01h%\x01@\x01\x04self\xc1\0\ tries\x01@\x01@\x01\x04self8\02\x04\0\x14[method]fields.clone\x01A\x01h&\x01@\x01\
\0\x0b\x04\0\x1f[method]incoming-request.method\x01B\x01@\x01\x04self\xc1\0\0\x0e\ \x04self\xc2\0\0\x0b\x04\0\x1f[method]incoming-request.method\x01C\x01@\x01\x04s\
\x04\0([method]incoming-request.path-with-query\x01C\x01k\x0d\x01@\x01\x04self\xc1\ elf\xc2\0\0\x0e\x04\0([method]incoming-request.path-with-query\x01D\x01k\x0d\x01\
\0\0\xc4\0\x04\0\x1f[method]incoming-request.scheme\x01E\x04\0\"[method]incoming\ @\x01\x04self\xc2\0\0\xc5\0\x04\0\x1f[method]incoming-request.scheme\x01F\x04\0\"\
-request.authority\x01C\x01i#\x01@\x01\x04self\xc1\0\0\xc6\0\x04\0\x20[method]in\ [method]incoming-request.authority\x01D\x01i$\x01@\x01\x04self\xc2\0\0\xc7\0\x04\
coming-request.headers\x01G\x01i,\x01j\x01\xc8\0\0\x01@\x01\x04self\xc1\0\0\xc9\0\ \0\x20[method]incoming-request.headers\x01H\x01i-\x01j\x01\xc9\0\0\x01@\x01\x04s\
\x04\0\x20[method]incoming-request.consume\x01J\x01i&\x01@\x01\x07headers\xc6\0\0\ elf\xc2\0\0\xca\0\x04\0\x20[method]incoming-request.consume\x01K\x01i'\x01@\x01\x07\
\xcb\0\x04\0\x1d[constructor]outgoing-request\x01L\x01h&\x01i/\x01j\x01\xce\0\0\x01\ headers\xc7\0\0\xcc\0\x04\0\x1d[constructor]outgoing-request\x01M\x01h'\x01i0\x01\
@\x01\x04self\xcd\0\0\xcf\0\x04\0\x1d[method]outgoing-request.body\x01P\x01@\x01\ j\x01\xcf\0\0\x01@\x01\x04self\xce\0\0\xd0\0\x04\0\x1d[method]outgoing-request.b\
\x04self\xcd\0\0\x0b\x04\0\x1f[method]outgoing-request.method\x01Q\x01j\0\0\x01@\ ody\x01Q\x01@\x01\x04self\xce\0\0\x0b\x04\0\x1f[method]outgoing-request.method\x01\
\x02\x04self\xcd\0\x06method\x0b\0\xd2\0\x04\0#[method]outgoing-request.set-meth\ R\x01j\0\0\x01@\x02\x04self\xce\0\x06method\x0b\0\xd3\0\x04\0#[method]outgoing-r\
od\x01S\x01@\x01\x04self\xcd\0\0\x0e\x04\0([method]outgoing-request.path-with-qu\ equest.set-method\x01T\x01@\x01\x04self\xce\0\0\x0e\x04\0([method]outgoing-reque\
ery\x01T\x01@\x02\x04self\xcd\0\x0fpath-with-query\x0e\0\xd2\0\x04\0,[method]out\ st.path-with-query\x01U\x01@\x02\x04self\xce\0\x0fpath-with-query\x0e\0\xd3\0\x04\
going-request.set-path-with-query\x01U\x01@\x01\x04self\xcd\0\0\xc4\0\x04\0\x1f[\ \0,[method]outgoing-request.set-path-with-query\x01V\x01@\x01\x04self\xce\0\0\xc5\
method]outgoing-request.scheme\x01V\x01@\x02\x04self\xcd\0\x06scheme\xc4\0\0\xd2\ \0\x04\0\x1f[method]outgoing-request.scheme\x01W\x01@\x02\x04self\xce\0\x06schem\
\0\x04\0#[method]outgoing-request.set-scheme\x01W\x04\0\"[method]outgoing-reques\ e\xc5\0\0\xd3\0\x04\0#[method]outgoing-request.set-scheme\x01X\x04\0\"[method]ou\
t.authority\x01T\x01@\x02\x04self\xcd\0\x09authority\x0e\0\xd2\0\x04\0&[method]o\ tgoing-request.authority\x01U\x01@\x02\x04self\xce\0\x09authority\x0e\0\xd3\0\x04\
utgoing-request.set-authority\x01X\x01@\x01\x04self\xcd\0\0\xc6\0\x04\0\x20[meth\ \0&[method]outgoing-request.set-authority\x01Y\x01@\x01\x04self\xce\0\0\xc7\0\x04\
od]outgoing-request.headers\x01Y\x01i'\x01@\0\0\xda\0\x04\0\x1c[constructor]requ\ \0\x20[method]outgoing-request.headers\x01Z\x01i(\x01@\0\0\xdb\0\x04\0\x1c[const\
est-options\x01[\x01h'\x01k\x01\x01@\x01\x04self\xdc\0\0\xdd\0\x04\0'[method]req\ ructor]request-options\x01\\\x01h(\x01k\x01\x01@\x01\x04self\xdd\0\0\xde\0\x04\0\
uest-options.connect-timeout\x01^\x01@\x02\x04self\xdc\0\x08duration\xdd\0\0\xd2\ '[method]request-options.connect-timeout\x01_\x01@\x02\x04self\xdd\0\x08duration\
\0\x04\0+[method]request-options.set-connect-timeout\x01_\x04\0*[method]request-\ \xde\0\0\xd3\0\x04\0+[method]request-options.set-connect-timeout\x01`\x04\0*[met\
options.first-byte-timeout\x01^\x04\0.[method]request-options.set-first-byte-tim\ hod]request-options.first-byte-timeout\x01_\x04\0.[method]request-options.set-fi\
eout\x01_\x04\0-[method]request-options.between-bytes-timeout\x01^\x04\01[method\ rst-byte-timeout\x01`\x04\0-[method]request-options.between-bytes-timeout\x01_\x04\
]request-options.set-between-bytes-timeout\x01_\x01i(\x01i.\x01j\x01\xe1\0\x01\x1b\ \01[method]request-options.set-between-bytes-timeout\x01`\x01i)\x01i/\x01j\x01\xe2\
\x01@\x02\x05param\xe0\0\x08response\xe2\0\x01\0\x04\0\x1d[static]response-outpa\ \0\x01\x1b\x01@\x02\x05param\xe1\0\x08response\xe3\0\x01\0\x04\0\x1d[static]resp\
ram.set\x01c\x01h+\x01@\x01\x04self\xe4\0\0*\x04\0\x20[method]incoming-response.\ onse-outparam.set\x01d\x01h,\x01@\x01\x04self\xe5\0\0+\x04\0\x20[method]incoming\
status\x01e\x01@\x01\x04self\xe4\0\0\xc6\0\x04\0![method]incoming-response.heade\ -response.status\x01f\x01@\x01\x04self\xe5\0\0\xc7\0\x04\0![method]incoming-resp\
rs\x01f\x01@\x01\x04self\xe4\0\0\xc9\0\x04\0![method]incoming-response.consume\x01\ onse.headers\x01g\x01@\x01\x04self\xe5\0\0\xca\0\x04\0![method]incoming-response\
g\x01h,\x01i\x03\x01j\x01\xe9\0\0\x01@\x01\x04self\xe8\0\0\xea\0\x04\0\x1c[metho\ .consume\x01h\x01h-\x01i\x03\x01j\x01\xea\0\0\x01@\x01\x04self\xe9\0\0\xeb\0\x04\
d]incoming-body.stream\x01k\x01i-\x01@\x01\x04this\xc8\0\0\xec\0\x04\0\x1c[stati\ \0\x1c[method]incoming-body.stream\x01l\x01i.\x01@\x01\x04this\xc9\0\0\xed\0\x04\
c]incoming-body.finish\x01m\x01h-\x01i\x09\x01@\x01\x04self\xee\0\0\xef\0\x04\0!\ \0\x1c[static]incoming-body.finish\x01n\x01h.\x01i\x09\x01@\x01\x04self\xef\0\0\xf0\
[method]future-trailers.subscribe\x01p\x01i$\x01k\xf1\0\x01j\x01\xf2\0\x01\x1b\x01\ \0\x04\0![method]future-trailers.subscribe\x01q\x01i%\x01k\xf2\0\x01j\x01\xf3\0\x01\
j\x01\xf3\0\0\x01k\xf4\0\x01@\x01\x04self\xee\0\0\xf5\0\x04\0\x1b[method]future-\ \x1b\x01j\x01\xf4\0\0\x01k\xf5\0\x01@\x01\x04self\xef\0\0\xf6\0\x04\0\x1b[method\
trailers.get\x01v\x01@\x01\x07headers\xc6\0\0\xe1\0\x04\0\x1e[constructor]outgoi\ ]future-trailers.get\x01w\x01@\x01\x07headers\xc7\0\0\xe2\0\x04\0\x1e[constructo\
ng-response\x01w\x01h.\x01@\x01\x04self\xf8\0\0*\x04\0%[method]outgoing-response\ r]outgoing-response\x01x\x01h/\x01@\x01\x04self\xf9\0\0+\x04\0%[method]outgoing-\
.status-code\x01y\x01@\x02\x04self\xf8\0\x0bstatus-code*\0\xd2\0\x04\0)[method]o\ response.status-code\x01z\x01@\x02\x04self\xf9\0\x0bstatus-code+\0\xd3\0\x04\0)[\
utgoing-response.set-status-code\x01z\x01@\x01\x04self\xf8\0\0\xc6\0\x04\0![meth\ method]outgoing-response.set-status-code\x01{\x01@\x01\x04self\xf9\0\0\xc7\0\x04\
od]outgoing-response.headers\x01{\x01@\x01\x04self\xf8\0\0\xcf\0\x04\0\x1e[metho\ \0![method]outgoing-response.headers\x01|\x01@\x01\x04self\xf9\0\0\xd0\0\x04\0\x1e\
d]outgoing-response.body\x01|\x01h/\x01i\x05\x01j\x01\xfe\0\0\x01@\x01\x04self\xfd\ [method]outgoing-response.body\x01}\x01h0\x01i\x05\x01j\x01\xff\0\0\x01@\x01\x04\
\0\0\xff\0\x04\0\x1b[method]outgoing-body.write\x01\x80\x01\x01j\0\x01\x1b\x01@\x02\ self\xfe\0\0\x80\x01\x04\0\x1b[method]outgoing-body.write\x01\x81\x01\x01j\0\x01\
\x04this\xce\0\x08trailers\xf2\0\0\x81\x01\x04\0\x1c[static]outgoing-body.finish\ \x1b\x01@\x02\x04this\xcf\0\x08trailers\xf3\0\0\x82\x01\x04\0\x1c[static]outgoin\
\x01\x82\x01\x01h0\x01@\x01\x04self\x83\x01\0\xef\0\x04\0*[method]future-incomin\ g-body.finish\x01\x83\x01\x01h1\x01@\x01\x04self\x84\x01\0\xf0\0\x04\0*[method]f\
g-response.subscribe\x01\x84\x01\x01i+\x01j\x01\x85\x01\x01\x1b\x01j\x01\x86\x01\ uture-incoming-response.subscribe\x01\x85\x01\x01i,\x01j\x01\x86\x01\x01\x1b\x01\
\0\x01k\x87\x01\x01@\x01\x04self\x83\x01\0\x88\x01\x04\0$[method]future-incoming\ j\x01\x87\x01\0\x01k\x88\x01\x01@\x01\x04self\x84\x01\0\x89\x01\x04\0$[method]fu\
-response.get\x01\x89\x01\x01h\x07\x01k\x1b\x01@\x01\x03err\x8a\x01\0\x8b\x01\x04\ ture-incoming-response.get\x01\x8a\x01\x01h\x07\x01k\x1b\x01@\x01\x03err\x8b\x01\
\0\x0fhttp-error-code\x01\x8c\x01\x03\x01\x15wasi:http/types@0.2.0\x05\x0d\x02\x03\ \0\x8c\x01\x04\0\x0fhttp-error-code\x01\x8d\x01\x03\0\x15wasi:http/types@0.2.4\x05\
\0\x08\x10outgoing-request\x02\x03\0\x08\x0frequest-options\x02\x03\0\x08\x18fut\ \x0e\x02\x03\0\x09\x10outgoing-request\x02\x03\0\x09\x0frequest-options\x02\x03\0\
ure-incoming-response\x02\x03\0\x08\x0aerror-code\x01B\x0f\x02\x03\x02\x01\x0e\x04\ \x09\x18future-incoming-response\x02\x03\0\x09\x0aerror-code\x01B\x0f\x02\x03\x02\
\0\x10outgoing-request\x03\0\0\x02\x03\x02\x01\x0f\x04\0\x0frequest-options\x03\0\ \x01\x0f\x04\0\x10outgoing-request\x03\0\0\x02\x03\x02\x01\x10\x04\0\x0frequest-\
\x02\x02\x03\x02\x01\x10\x04\0\x18future-incoming-response\x03\0\x04\x02\x03\x02\ options\x03\0\x02\x02\x03\x02\x01\x11\x04\0\x18future-incoming-response\x03\0\x04\
\x01\x11\x04\0\x0aerror-code\x03\0\x06\x01i\x01\x01i\x03\x01k\x09\x01i\x05\x01j\x01\ \x02\x03\x02\x01\x12\x04\0\x0aerror-code\x03\0\x06\x01i\x01\x01i\x03\x01k\x09\x01\
\x0b\x01\x07\x01@\x02\x07request\x08\x07options\x0a\0\x0c\x04\0\x06handle\x01\x0d\ i\x05\x01j\x01\x0b\x01\x07\x01@\x02\x07request\x08\x07options\x0a\0\x0c\x04\0\x06\
\x03\x01\x20wasi:http/outgoing-handler@0.2.0\x05\x12\x01B\x05\x01r\x02\x07second\ handle\x01\x0d\x03\0\x20wasi:http/outgoing-handler@0.2.4\x05\x13\x02\x03\0\x09\x10\
sw\x0bnanosecondsy\x04\0\x08datetime\x03\0\0\x01@\0\0\x01\x04\0\x03now\x01\x02\x04\ incoming-request\x02\x03\0\x09\x11response-outparam\x01B\x08\x02\x03\x02\x01\x14\
\0\x0aresolution\x01\x02\x03\x01\x1cwasi:clocks/wall-clock@0.2.0\x05\x13\x02\x03\ \x04\0\x10incoming-request\x03\0\0\x02\x03\x02\x01\x15\x04\0\x11response-outpara\
\0\x08\x10incoming-request\x02\x03\0\x08\x11response-outparam\x01B\x08\x02\x03\x02\ m\x03\0\x02\x01i\x01\x01i\x03\x01@\x02\x07request\x04\x0cresponse-out\x05\x01\0\x04\
\x01\x14\x04\0\x10incoming-request\x03\0\0\x02\x03\x02\x01\x15\x04\0\x11response\ \0\x06handle\x01\x06\x04\0\x20wasi:http/incoming-handler@0.2.4\x05\x16\x04\0\x15\
-outparam\x03\0\x02\x01i\x01\x01i\x03\x01@\x02\x07request\x04\x0cresponse-out\x05\ wasi:http/proxy@0.2.4\x04\0\x0b\x0b\x01\0\x05proxy\x03\0\0\0G\x09producers\x01\x0c\
\x01\0\x04\0\x06handle\x01\x06\x04\x01\x20wasi:http/incoming-handler@0.2.0\x05\x16\ processed-by\x02\x0dwit-component\x070.225.0\x10wit-bindgen-rust\x060.39.0";
\x04\x01\x15wasi:http/proxy@0.2.0\x04\0\x0b\x0b\x01\0\x05proxy\x03\0\0\0G\x09pro\ };
ducers\x01\x0cprocessed-by\x02\x0dwit-component\x070.201.0\x10wit-bindgen-rust\x06\ };
0.21.0";
};
)
} }
#[doc(inline)] #[doc(inline)]
pub use __export_proxy_impl as _export_proxy; pub use __export_proxy_impl as _export_proxy;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
#[link_section = "component-type:wit-bindgen:0.21.0:proxy-with-all-of-its-exports-removed:encoded worldrust-wasi-from-crates-io-proxy-world"] #[unsafe(
link_section = "component-type:wit-bindgen:0.39.0:wasi:http@0.2.4:proxy-with-all-of-its-exports-removed:encoded worldrust-wasi-from-crates-io-proxy-world"
)]
#[doc(hidden)] #[doc(hidden)]
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 6905] = *b"\ #[allow(clippy::octal_escapes)]
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xdd4\x01A\x02\x01A\x1f\ pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 6921] = *b"\
\x01B\x05\x01p}\x01@\x01\x03lenw\0\0\x04\0\x10get-random-bytes\x01\x01\x01@\0\0w\ \0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xed4\x01A\x02\x01A\x1f\
\x04\0\x0eget-random-u64\x01\x02\x03\x01\x18wasi:random/random@0.2.0\x05\0\x01B\x04\ \x01B\x0a\x04\0\x08pollable\x03\x01\x01h\0\x01@\x01\x04self\x01\0\x7f\x04\0\x16[\
\x04\0\x05error\x03\x01\x01h\0\x01@\x01\x04self\x01\0s\x04\0\x1d[method]error.to\ method]pollable.ready\x01\x02\x01@\x01\x04self\x01\x01\0\x04\0\x16[method]pollab\
-debug-string\x01\x02\x03\x01\x13wasi:io/error@0.2.0\x05\x01\x01B\x0a\x04\0\x08p\ le.block\x01\x03\x01p\x01\x01py\x01@\x01\x02in\x04\0\x05\x04\0\x04poll\x01\x06\x03\
ollable\x03\x01\x01h\0\x01@\x01\x04self\x01\0\x7f\x04\0\x16[method]pollable.read\ \0\x12wasi:io/poll@0.2.4\x05\0\x02\x03\0\0\x08pollable\x01B\x0f\x02\x03\x02\x01\x01\
y\x01\x02\x01@\x01\x04self\x01\x01\0\x04\0\x16[method]pollable.block\x01\x03\x01\ \x04\0\x08pollable\x03\0\0\x01w\x04\0\x07instant\x03\0\x02\x01w\x04\0\x08duratio\
p\x01\x01py\x01@\x01\x02in\x04\0\x05\x04\0\x04poll\x01\x06\x03\x01\x12wasi:io/po\ n\x03\0\x04\x01@\0\0\x03\x04\0\x03now\x01\x06\x01@\0\0\x05\x04\0\x0aresolution\x01\
ll@0.2.0\x05\x02\x02\x03\0\x01\x05error\x02\x03\0\x02\x08pollable\x01B(\x02\x03\x02\ \x07\x01i\x01\x01@\x01\x04when\x03\0\x08\x04\0\x11subscribe-instant\x01\x09\x01@\
\x01\x03\x04\0\x05error\x03\0\0\x02\x03\x02\x01\x04\x04\0\x08pollable\x03\0\x02\x01\ \x01\x04when\x05\0\x08\x04\0\x12subscribe-duration\x01\x0a\x03\0!wasi:clocks/mon\
i\x01\x01q\x02\x15last-operation-failed\x01\x04\0\x06closed\0\0\x04\0\x0cstream-\ otonic-clock@0.2.4\x05\x02\x01B\x05\x01r\x02\x07secondsw\x0bnanosecondsy\x04\0\x08\
error\x03\0\x05\x04\0\x0cinput-stream\x03\x01\x04\0\x0doutput-stream\x03\x01\x01\ datetime\x03\0\0\x01@\0\0\x01\x04\0\x03now\x01\x02\x04\0\x0aresolution\x01\x02\x03\
h\x07\x01p}\x01j\x01\x0a\x01\x06\x01@\x02\x04self\x09\x03lenw\0\x0b\x04\0\x19[me\ \0\x1cwasi:clocks/wall-clock@0.2.4\x05\x03\x01B\x05\x01p}\x01@\x01\x03lenw\0\0\x04\
thod]input-stream.read\x01\x0c\x04\0\"[method]input-stream.blocking-read\x01\x0c\ \0\x10get-random-bytes\x01\x01\x01@\0\0w\x04\0\x0eget-random-u64\x01\x02\x03\0\x18\
\x01j\x01w\x01\x06\x01@\x02\x04self\x09\x03lenw\0\x0d\x04\0\x19[method]input-str\ wasi:random/random@0.2.4\x05\x04\x01B\x04\x04\0\x05error\x03\x01\x01h\0\x01@\x01\
eam.skip\x01\x0e\x04\0\"[method]input-stream.blocking-skip\x01\x0e\x01i\x03\x01@\ \x04self\x01\0s\x04\0\x1d[method]error.to-debug-string\x01\x02\x03\0\x13wasi:io/\
\x01\x04self\x09\0\x0f\x04\0\x1e[method]input-stream.subscribe\x01\x10\x01h\x08\x01\ error@0.2.4\x05\x05\x02\x03\0\x04\x05error\x01B(\x02\x03\x02\x01\x06\x04\0\x05er\
@\x01\x04self\x11\0\x0d\x04\0![method]output-stream.check-write\x01\x12\x01j\0\x01\ ror\x03\0\0\x02\x03\x02\x01\x01\x04\0\x08pollable\x03\0\x02\x01i\x01\x01q\x02\x15\
\x06\x01@\x02\x04self\x11\x08contents\x0a\0\x13\x04\0\x1b[method]output-stream.w\ last-operation-failed\x01\x04\0\x06closed\0\0\x04\0\x0cstream-error\x03\0\x05\x04\
rite\x01\x14\x04\0.[method]output-stream.blocking-write-and-flush\x01\x14\x01@\x01\ \0\x0cinput-stream\x03\x01\x04\0\x0doutput-stream\x03\x01\x01h\x07\x01p}\x01j\x01\
\x04self\x11\0\x13\x04\0\x1b[method]output-stream.flush\x01\x15\x04\0$[method]ou\ \x0a\x01\x06\x01@\x02\x04self\x09\x03lenw\0\x0b\x04\0\x19[method]input-stream.re\
tput-stream.blocking-flush\x01\x15\x01@\x01\x04self\x11\0\x0f\x04\0\x1f[method]o\ ad\x01\x0c\x04\0\"[method]input-stream.blocking-read\x01\x0c\x01j\x01w\x01\x06\x01\
utput-stream.subscribe\x01\x16\x01@\x02\x04self\x11\x03lenw\0\x13\x04\0\"[method\ @\x02\x04self\x09\x03lenw\0\x0d\x04\0\x19[method]input-stream.skip\x01\x0e\x04\0\
]output-stream.write-zeroes\x01\x17\x04\05[method]output-stream.blocking-write-z\ \"[method]input-stream.blocking-skip\x01\x0e\x01i\x03\x01@\x01\x04self\x09\0\x0f\
eroes-and-flush\x01\x17\x01@\x03\x04self\x11\x03src\x09\x03lenw\0\x0d\x04\0\x1c[\ \x04\0\x1e[method]input-stream.subscribe\x01\x10\x01h\x08\x01@\x01\x04self\x11\0\
method]output-stream.splice\x01\x18\x04\0%[method]output-stream.blocking-splice\x01\ \x0d\x04\0![method]output-stream.check-write\x01\x12\x01j\0\x01\x06\x01@\x02\x04\
\x18\x03\x01\x15wasi:io/streams@0.2.0\x05\x05\x02\x03\0\x03\x0doutput-stream\x01\ self\x11\x08contents\x0a\0\x13\x04\0\x1b[method]output-stream.write\x01\x14\x04\0\
B\x05\x02\x03\x02\x01\x06\x04\0\x0doutput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\ .[method]output-stream.blocking-write-and-flush\x01\x14\x01@\x01\x04self\x11\0\x13\
\0\x0aget-stdout\x01\x03\x03\x01\x15wasi:cli/stdout@0.2.0\x05\x07\x01B\x05\x02\x03\ \x04\0\x1b[method]output-stream.flush\x01\x15\x04\0$[method]output-stream.blocki\
\x02\x01\x06\x04\0\x0doutput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\0\x0aget-s\ ng-flush\x01\x15\x01@\x01\x04self\x11\0\x0f\x04\0\x1f[method]output-stream.subsc\
tderr\x01\x03\x03\x01\x15wasi:cli/stderr@0.2.0\x05\x08\x02\x03\0\x03\x0cinput-st\ ribe\x01\x16\x01@\x02\x04self\x11\x03lenw\0\x13\x04\0\"[method]output-stream.wri\
ream\x01B\x05\x02\x03\x02\x01\x09\x04\0\x0cinput-stream\x03\0\0\x01i\x01\x01@\0\0\ te-zeroes\x01\x17\x04\05[method]output-stream.blocking-write-zeroes-and-flush\x01\
\x02\x04\0\x09get-stdin\x01\x03\x03\x01\x14wasi:cli/stdin@0.2.0\x05\x0a\x01B\x0f\ \x17\x01@\x03\x04self\x11\x03src\x09\x03lenw\0\x0d\x04\0\x1c[method]output-strea\
\x02\x03\x02\x01\x04\x04\0\x08pollable\x03\0\0\x01w\x04\0\x07instant\x03\0\x02\x01\ m.splice\x01\x18\x04\0%[method]output-stream.blocking-splice\x01\x18\x03\0\x15wa\
w\x04\0\x08duration\x03\0\x04\x01@\0\0\x03\x04\0\x03now\x01\x06\x01@\0\0\x05\x04\ si:io/streams@0.2.4\x05\x07\x02\x03\0\x05\x0doutput-stream\x01B\x05\x02\x03\x02\x01\
\0\x0aresolution\x01\x07\x01i\x01\x01@\x01\x04when\x03\0\x08\x04\0\x11subscribe-\ \x08\x04\0\x0doutput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\0\x0aget-stdout\x01\
instant\x01\x09\x01@\x01\x04when\x05\0\x08\x04\0\x12subscribe-duration\x01\x0a\x03\ \x03\x03\0\x15wasi:cli/stdout@0.2.4\x05\x09\x01B\x05\x02\x03\x02\x01\x08\x04\0\x0d\
\x01!wasi:clocks/monotonic-clock@0.2.0\x05\x0b\x02\x03\0\x07\x08duration\x01B\xc0\ output-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\0\x0aget-stderr\x01\x03\x03\0\x15\
\x01\x02\x03\x02\x01\x0c\x04\0\x08duration\x03\0\0\x02\x03\x02\x01\x09\x04\0\x0c\ wasi:cli/stderr@0.2.4\x05\x0a\x02\x03\0\x05\x0cinput-stream\x01B\x05\x02\x03\x02\
input-stream\x03\0\x02\x02\x03\x02\x01\x06\x04\0\x0doutput-stream\x03\0\x04\x02\x03\ \x01\x0b\x04\0\x0cinput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\0\x09get-stdin\x01\
\x02\x01\x03\x04\0\x08io-error\x03\0\x06\x02\x03\x02\x01\x04\x04\0\x08pollable\x03\ \x03\x03\0\x14wasi:cli/stdin@0.2.4\x05\x0c\x02\x03\0\x01\x08duration\x01B\xc1\x01\
\0\x08\x01q\x0a\x03get\0\0\x04head\0\0\x04post\0\0\x03put\0\0\x06delete\0\0\x07c\ \x02\x03\x02\x01\x0d\x04\0\x08duration\x03\0\0\x02\x03\x02\x01\x0b\x04\0\x0cinpu\
onnect\0\0\x07options\0\0\x05trace\0\0\x05patch\0\0\x05other\x01s\0\x04\0\x06met\ t-stream\x03\0\x02\x02\x03\x02\x01\x08\x04\0\x0doutput-stream\x03\0\x04\x02\x03\x02\
hod\x03\0\x0a\x01q\x03\x04HTTP\0\0\x05HTTPS\0\0\x05other\x01s\0\x04\0\x06scheme\x03\ \x01\x06\x04\0\x08io-error\x03\0\x06\x02\x03\x02\x01\x01\x04\0\x08pollable\x03\0\
\x08\x01q\x0a\x03get\0\0\x04head\0\0\x04post\0\0\x03put\0\0\x06delete\0\0\x07con\
nect\0\0\x07options\0\0\x05trace\0\0\x05patch\0\0\x05other\x01s\0\x04\0\x06metho\
d\x03\0\x0a\x01q\x03\x04HTTP\0\0\x05HTTPS\0\0\x05other\x01s\0\x04\0\x06scheme\x03\
\0\x0c\x01ks\x01k{\x01r\x02\x05rcode\x0e\x09info-code\x0f\x04\0\x11DNS-error-pay\ \0\x0c\x01ks\x01k{\x01r\x02\x05rcode\x0e\x09info-code\x0f\x04\0\x11DNS-error-pay\
load\x03\0\x10\x01k}\x01r\x02\x08alert-id\x12\x0dalert-message\x0e\x04\0\x1aTLS-\ load\x03\0\x10\x01k}\x01r\x02\x08alert-id\x12\x0dalert-message\x0e\x04\0\x1aTLS-\
alert-received-payload\x03\0\x13\x01ky\x01r\x02\x0afield-name\x0e\x0afield-size\x15\ alert-received-payload\x03\0\x13\x01ky\x01r\x02\x0afield-name\x0e\x0afield-size\x15\
@@ -329,83 +348,79 @@ TP-response-header-section-size\x01\x15\0\x19HTTP-response-header-size\x01\x17\0
P-upgrade-failed\0\0\x13HTTP-protocol-error\0\0\x0dloop-detected\0\0\x13configur\ P-upgrade-failed\0\0\x13HTTP-protocol-error\0\0\x0dloop-detected\0\0\x13configur\
ation-error\0\0\x0einternal-error\x01\x0e\0\x04\0\x0aerror-code\x03\0\x1a\x01q\x03\ ation-error\0\0\x0einternal-error\x01\x0e\0\x04\0\x0aerror-code\x03\0\x1a\x01q\x03\
\x0einvalid-syntax\0\0\x09forbidden\0\0\x09immutable\0\0\x04\0\x0cheader-error\x03\ \x0einvalid-syntax\0\0\x09forbidden\0\0\x09immutable\0\0\x04\0\x0cheader-error\x03\
\0\x1c\x01s\x04\0\x09field-key\x03\0\x1e\x01p}\x04\0\x0bfield-value\x03\0\x20\x04\ \0\x1c\x01s\x04\0\x09field-key\x03\0\x1e\x04\0\x0afield-name\x03\0\x1f\x01p}\x04\
\0\x06fields\x03\x01\x04\0\x07headers\x03\0\"\x04\0\x08trailers\x03\0\"\x04\0\x10\ \0\x0bfield-value\x03\0!\x04\0\x06fields\x03\x01\x04\0\x07headers\x03\0#\x04\0\x08\
incoming-request\x03\x01\x04\0\x10outgoing-request\x03\x01\x04\0\x0frequest-opti\ trailers\x03\0#\x04\0\x10incoming-request\x03\x01\x04\0\x10outgoing-request\x03\x01\
ons\x03\x01\x04\0\x11response-outparam\x03\x01\x01{\x04\0\x0bstatus-code\x03\0)\x04\ \x04\0\x0frequest-options\x03\x01\x04\0\x11response-outparam\x03\x01\x01{\x04\0\x0b\
\0\x11incoming-response\x03\x01\x04\0\x0dincoming-body\x03\x01\x04\0\x0ffuture-t\ status-code\x03\0*\x04\0\x11incoming-response\x03\x01\x04\0\x0dincoming-body\x03\
railers\x03\x01\x04\0\x11outgoing-response\x03\x01\x04\0\x0doutgoing-body\x03\x01\ \x01\x04\0\x0ffuture-trailers\x03\x01\x04\0\x11outgoing-response\x03\x01\x04\0\x0d\
\x04\0\x18future-incoming-response\x03\x01\x01i\"\x01@\0\01\x04\0\x13[constructo\ outgoing-body\x03\x01\x04\0\x18future-incoming-response\x03\x01\x01i#\x01@\0\02\x04\
r]fields\x012\x01o\x02\x1f!\x01p3\x01j\x011\x01\x1d\x01@\x01\x07entries4\05\x04\0\ \0\x13[constructor]fields\x013\x01o\x02\x20\"\x01p4\x01j\x012\x01\x1d\x01@\x01\x07\
\x18[static]fields.from-list\x016\x01h\"\x01p!\x01@\x02\x04self7\x04name\x1f\08\x04\ entries5\06\x04\0\x18[static]fields.from-list\x017\x01h#\x01p\"\x01@\x02\x04self\
\0\x12[method]fields.get\x019\x01@\x02\x04self7\x04name\x1f\0\x7f\x04\0\x12[meth\ 8\x04name\x20\09\x04\0\x12[method]fields.get\x01:\x01@\x02\x04self8\x04name\x20\0\
od]fields.has\x01:\x01j\0\x01\x1d\x01@\x03\x04self7\x04name\x1f\x05value8\0;\x04\ \x7f\x04\0\x12[method]fields.has\x01;\x01j\0\x01\x1d\x01@\x03\x04self8\x04name\x20\
\0\x12[method]fields.set\x01<\x01@\x02\x04self7\x04name\x1f\0;\x04\0\x15[method]\ \x05value9\0<\x04\0\x12[method]fields.set\x01=\x01@\x02\x04self8\x04name\x20\0<\x04\
fields.delete\x01=\x01@\x03\x04self7\x04name\x1f\x05value!\0;\x04\0\x15[method]f\ \0\x15[method]fields.delete\x01>\x01@\x03\x04self8\x04name\x20\x05value\"\0<\x04\
ields.append\x01>\x01@\x01\x04self7\04\x04\0\x16[method]fields.entries\x01?\x01@\ \0\x15[method]fields.append\x01?\x01@\x01\x04self8\05\x04\0\x16[method]fields.en\
\x01\x04self7\01\x04\0\x14[method]fields.clone\x01@\x01h%\x01@\x01\x04self\xc1\0\ tries\x01@\x01@\x01\x04self8\02\x04\0\x14[method]fields.clone\x01A\x01h&\x01@\x01\
\0\x0b\x04\0\x1f[method]incoming-request.method\x01B\x01@\x01\x04self\xc1\0\0\x0e\ \x04self\xc2\0\0\x0b\x04\0\x1f[method]incoming-request.method\x01C\x01@\x01\x04s\
\x04\0([method]incoming-request.path-with-query\x01C\x01k\x0d\x01@\x01\x04self\xc1\ elf\xc2\0\0\x0e\x04\0([method]incoming-request.path-with-query\x01D\x01k\x0d\x01\
\0\0\xc4\0\x04\0\x1f[method]incoming-request.scheme\x01E\x04\0\"[method]incoming\ @\x01\x04self\xc2\0\0\xc5\0\x04\0\x1f[method]incoming-request.scheme\x01F\x04\0\"\
-request.authority\x01C\x01i#\x01@\x01\x04self\xc1\0\0\xc6\0\x04\0\x20[method]in\ [method]incoming-request.authority\x01D\x01i$\x01@\x01\x04self\xc2\0\0\xc7\0\x04\
coming-request.headers\x01G\x01i,\x01j\x01\xc8\0\0\x01@\x01\x04self\xc1\0\0\xc9\0\ \0\x20[method]incoming-request.headers\x01H\x01i-\x01j\x01\xc9\0\0\x01@\x01\x04s\
\x04\0\x20[method]incoming-request.consume\x01J\x01i&\x01@\x01\x07headers\xc6\0\0\ elf\xc2\0\0\xca\0\x04\0\x20[method]incoming-request.consume\x01K\x01i'\x01@\x01\x07\
\xcb\0\x04\0\x1d[constructor]outgoing-request\x01L\x01h&\x01i/\x01j\x01\xce\0\0\x01\ headers\xc7\0\0\xcc\0\x04\0\x1d[constructor]outgoing-request\x01M\x01h'\x01i0\x01\
@\x01\x04self\xcd\0\0\xcf\0\x04\0\x1d[method]outgoing-request.body\x01P\x01@\x01\ j\x01\xcf\0\0\x01@\x01\x04self\xce\0\0\xd0\0\x04\0\x1d[method]outgoing-request.b\
\x04self\xcd\0\0\x0b\x04\0\x1f[method]outgoing-request.method\x01Q\x01j\0\0\x01@\ ody\x01Q\x01@\x01\x04self\xce\0\0\x0b\x04\0\x1f[method]outgoing-request.method\x01\
\x02\x04self\xcd\0\x06method\x0b\0\xd2\0\x04\0#[method]outgoing-request.set-meth\ R\x01j\0\0\x01@\x02\x04self\xce\0\x06method\x0b\0\xd3\0\x04\0#[method]outgoing-r\
od\x01S\x01@\x01\x04self\xcd\0\0\x0e\x04\0([method]outgoing-request.path-with-qu\ equest.set-method\x01T\x01@\x01\x04self\xce\0\0\x0e\x04\0([method]outgoing-reque\
ery\x01T\x01@\x02\x04self\xcd\0\x0fpath-with-query\x0e\0\xd2\0\x04\0,[method]out\ st.path-with-query\x01U\x01@\x02\x04self\xce\0\x0fpath-with-query\x0e\0\xd3\0\x04\
going-request.set-path-with-query\x01U\x01@\x01\x04self\xcd\0\0\xc4\0\x04\0\x1f[\ \0,[method]outgoing-request.set-path-with-query\x01V\x01@\x01\x04self\xce\0\0\xc5\
method]outgoing-request.scheme\x01V\x01@\x02\x04self\xcd\0\x06scheme\xc4\0\0\xd2\ \0\x04\0\x1f[method]outgoing-request.scheme\x01W\x01@\x02\x04self\xce\0\x06schem\
\0\x04\0#[method]outgoing-request.set-scheme\x01W\x04\0\"[method]outgoing-reques\ e\xc5\0\0\xd3\0\x04\0#[method]outgoing-request.set-scheme\x01X\x04\0\"[method]ou\
t.authority\x01T\x01@\x02\x04self\xcd\0\x09authority\x0e\0\xd2\0\x04\0&[method]o\ tgoing-request.authority\x01U\x01@\x02\x04self\xce\0\x09authority\x0e\0\xd3\0\x04\
utgoing-request.set-authority\x01X\x01@\x01\x04self\xcd\0\0\xc6\0\x04\0\x20[meth\ \0&[method]outgoing-request.set-authority\x01Y\x01@\x01\x04self\xce\0\0\xc7\0\x04\
od]outgoing-request.headers\x01Y\x01i'\x01@\0\0\xda\0\x04\0\x1c[constructor]requ\ \0\x20[method]outgoing-request.headers\x01Z\x01i(\x01@\0\0\xdb\0\x04\0\x1c[const\
est-options\x01[\x01h'\x01k\x01\x01@\x01\x04self\xdc\0\0\xdd\0\x04\0'[method]req\ ructor]request-options\x01\\\x01h(\x01k\x01\x01@\x01\x04self\xdd\0\0\xde\0\x04\0\
uest-options.connect-timeout\x01^\x01@\x02\x04self\xdc\0\x08duration\xdd\0\0\xd2\ '[method]request-options.connect-timeout\x01_\x01@\x02\x04self\xdd\0\x08duration\
\0\x04\0+[method]request-options.set-connect-timeout\x01_\x04\0*[method]request-\ \xde\0\0\xd3\0\x04\0+[method]request-options.set-connect-timeout\x01`\x04\0*[met\
options.first-byte-timeout\x01^\x04\0.[method]request-options.set-first-byte-tim\ hod]request-options.first-byte-timeout\x01_\x04\0.[method]request-options.set-fi\
eout\x01_\x04\0-[method]request-options.between-bytes-timeout\x01^\x04\01[method\ rst-byte-timeout\x01`\x04\0-[method]request-options.between-bytes-timeout\x01_\x04\
]request-options.set-between-bytes-timeout\x01_\x01i(\x01i.\x01j\x01\xe1\0\x01\x1b\ \01[method]request-options.set-between-bytes-timeout\x01`\x01i)\x01i/\x01j\x01\xe2\
\x01@\x02\x05param\xe0\0\x08response\xe2\0\x01\0\x04\0\x1d[static]response-outpa\ \0\x01\x1b\x01@\x02\x05param\xe1\0\x08response\xe3\0\x01\0\x04\0\x1d[static]resp\
ram.set\x01c\x01h+\x01@\x01\x04self\xe4\0\0*\x04\0\x20[method]incoming-response.\ onse-outparam.set\x01d\x01h,\x01@\x01\x04self\xe5\0\0+\x04\0\x20[method]incoming\
status\x01e\x01@\x01\x04self\xe4\0\0\xc6\0\x04\0![method]incoming-response.heade\ -response.status\x01f\x01@\x01\x04self\xe5\0\0\xc7\0\x04\0![method]incoming-resp\
rs\x01f\x01@\x01\x04self\xe4\0\0\xc9\0\x04\0![method]incoming-response.consume\x01\ onse.headers\x01g\x01@\x01\x04self\xe5\0\0\xca\0\x04\0![method]incoming-response\
g\x01h,\x01i\x03\x01j\x01\xe9\0\0\x01@\x01\x04self\xe8\0\0\xea\0\x04\0\x1c[metho\ .consume\x01h\x01h-\x01i\x03\x01j\x01\xea\0\0\x01@\x01\x04self\xe9\0\0\xeb\0\x04\
d]incoming-body.stream\x01k\x01i-\x01@\x01\x04this\xc8\0\0\xec\0\x04\0\x1c[stati\ \0\x1c[method]incoming-body.stream\x01l\x01i.\x01@\x01\x04this\xc9\0\0\xed\0\x04\
c]incoming-body.finish\x01m\x01h-\x01i\x09\x01@\x01\x04self\xee\0\0\xef\0\x04\0!\ \0\x1c[static]incoming-body.finish\x01n\x01h.\x01i\x09\x01@\x01\x04self\xef\0\0\xf0\
[method]future-trailers.subscribe\x01p\x01i$\x01k\xf1\0\x01j\x01\xf2\0\x01\x1b\x01\ \0\x04\0![method]future-trailers.subscribe\x01q\x01i%\x01k\xf2\0\x01j\x01\xf3\0\x01\
j\x01\xf3\0\0\x01k\xf4\0\x01@\x01\x04self\xee\0\0\xf5\0\x04\0\x1b[method]future-\ \x1b\x01j\x01\xf4\0\0\x01k\xf5\0\x01@\x01\x04self\xef\0\0\xf6\0\x04\0\x1b[method\
trailers.get\x01v\x01@\x01\x07headers\xc6\0\0\xe1\0\x04\0\x1e[constructor]outgoi\ ]future-trailers.get\x01w\x01@\x01\x07headers\xc7\0\0\xe2\0\x04\0\x1e[constructo\
ng-response\x01w\x01h.\x01@\x01\x04self\xf8\0\0*\x04\0%[method]outgoing-response\ r]outgoing-response\x01x\x01h/\x01@\x01\x04self\xf9\0\0+\x04\0%[method]outgoing-\
.status-code\x01y\x01@\x02\x04self\xf8\0\x0bstatus-code*\0\xd2\0\x04\0)[method]o\ response.status-code\x01z\x01@\x02\x04self\xf9\0\x0bstatus-code+\0\xd3\0\x04\0)[\
utgoing-response.set-status-code\x01z\x01@\x01\x04self\xf8\0\0\xc6\0\x04\0![meth\ method]outgoing-response.set-status-code\x01{\x01@\x01\x04self\xf9\0\0\xc7\0\x04\
od]outgoing-response.headers\x01{\x01@\x01\x04self\xf8\0\0\xcf\0\x04\0\x1e[metho\ \0![method]outgoing-response.headers\x01|\x01@\x01\x04self\xf9\0\0\xd0\0\x04\0\x1e\
d]outgoing-response.body\x01|\x01h/\x01i\x05\x01j\x01\xfe\0\0\x01@\x01\x04self\xfd\ [method]outgoing-response.body\x01}\x01h0\x01i\x05\x01j\x01\xff\0\0\x01@\x01\x04\
\0\0\xff\0\x04\0\x1b[method]outgoing-body.write\x01\x80\x01\x01j\0\x01\x1b\x01@\x02\ self\xfe\0\0\x80\x01\x04\0\x1b[method]outgoing-body.write\x01\x81\x01\x01j\0\x01\
\x04this\xce\0\x08trailers\xf2\0\0\x81\x01\x04\0\x1c[static]outgoing-body.finish\ \x1b\x01@\x02\x04this\xcf\0\x08trailers\xf3\0\0\x82\x01\x04\0\x1c[static]outgoin\
\x01\x82\x01\x01h0\x01@\x01\x04self\x83\x01\0\xef\0\x04\0*[method]future-incomin\ g-body.finish\x01\x83\x01\x01h1\x01@\x01\x04self\x84\x01\0\xf0\0\x04\0*[method]f\
g-response.subscribe\x01\x84\x01\x01i+\x01j\x01\x85\x01\x01\x1b\x01j\x01\x86\x01\ uture-incoming-response.subscribe\x01\x85\x01\x01i,\x01j\x01\x86\x01\x01\x1b\x01\
\0\x01k\x87\x01\x01@\x01\x04self\x83\x01\0\x88\x01\x04\0$[method]future-incoming\ j\x01\x87\x01\0\x01k\x88\x01\x01@\x01\x04self\x84\x01\0\x89\x01\x04\0$[method]fu\
-response.get\x01\x89\x01\x01h\x07\x01k\x1b\x01@\x01\x03err\x8a\x01\0\x8b\x01\x04\ ture-incoming-response.get\x01\x8a\x01\x01h\x07\x01k\x1b\x01@\x01\x03err\x8b\x01\
\0\x0fhttp-error-code\x01\x8c\x01\x03\x01\x15wasi:http/types@0.2.0\x05\x0d\x02\x03\ \0\x8c\x01\x04\0\x0fhttp-error-code\x01\x8d\x01\x03\0\x15wasi:http/types@0.2.4\x05\
\0\x08\x10outgoing-request\x02\x03\0\x08\x0frequest-options\x02\x03\0\x08\x18fut\ \x0e\x02\x03\0\x09\x10outgoing-request\x02\x03\0\x09\x0frequest-options\x02\x03\0\
ure-incoming-response\x02\x03\0\x08\x0aerror-code\x01B\x0f\x02\x03\x02\x01\x0e\x04\ \x09\x18future-incoming-response\x02\x03\0\x09\x0aerror-code\x01B\x0f\x02\x03\x02\
\0\x10outgoing-request\x03\0\0\x02\x03\x02\x01\x0f\x04\0\x0frequest-options\x03\0\ \x01\x0f\x04\0\x10outgoing-request\x03\0\0\x02\x03\x02\x01\x10\x04\0\x0frequest-\
\x02\x02\x03\x02\x01\x10\x04\0\x18future-incoming-response\x03\0\x04\x02\x03\x02\ options\x03\0\x02\x02\x03\x02\x01\x11\x04\0\x18future-incoming-response\x03\0\x04\
\x01\x11\x04\0\x0aerror-code\x03\0\x06\x01i\x01\x01i\x03\x01k\x09\x01i\x05\x01j\x01\ \x02\x03\x02\x01\x12\x04\0\x0aerror-code\x03\0\x06\x01i\x01\x01i\x03\x01k\x09\x01\
\x0b\x01\x07\x01@\x02\x07request\x08\x07options\x0a\0\x0c\x04\0\x06handle\x01\x0d\ i\x05\x01j\x01\x0b\x01\x07\x01@\x02\x07request\x08\x07options\x0a\0\x0c\x04\0\x06\
\x03\x01\x20wasi:http/outgoing-handler@0.2.0\x05\x12\x01B\x05\x01r\x02\x07second\ handle\x01\x0d\x03\0\x20wasi:http/outgoing-handler@0.2.4\x05\x13\x04\05wasi:http\
sw\x0bnanosecondsy\x04\0\x08datetime\x03\0\0\x01@\0\0\x01\x04\0\x03now\x01\x02\x04\ /proxy-with-all-of-its-exports-removed@0.2.4\x04\0\x0b+\x01\0%proxy-with-all-of-\
\0\x0aresolution\x01\x02\x03\x01\x1cwasi:clocks/wall-clock@0.2.0\x05\x13\x04\x01\ its-exports-removed\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-compo\
5wasi:http/proxy-with-all-of-its-exports-removed@0.2.0\x04\0\x0b+\x01\0%proxy-wi\ nent\x070.225.0\x10wit-bindgen-rust\x060.39.0";
th-all-of-its-exports-removed\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0d\
wit-component\x070.201.0\x10wit-bindgen-rust\x060.21.0";
#[inline(never)] #[inline(never)]
#[doc(hidden)] #[doc(hidden)]
#[cfg(target_arch = "wasm32")]
pub fn __link_custom_section_describing_imports() { pub fn __link_custom_section_describing_imports() {
wit_bindgen_rt::maybe_link_cabi_realloc(); wit_bindgen_rt::maybe_link_cabi_realloc();
} }

View File

@@ -1,7 +1,10 @@
package wasi:cli@0.2.0; package wasi:cli@0.2.4;
@since(version = 0.2.0)
world command { world command {
@since(version = 0.2.0)
include imports; include imports;
@since(version = 0.2.0)
export run; export run;
} }

View File

@@ -1,3 +1,4 @@
@since(version = 0.2.0)
interface environment { interface environment {
/// Get the POSIX-style environment variables. /// Get the POSIX-style environment variables.
/// ///
@@ -7,12 +8,15 @@ interface environment {
/// Morally, these are a value import, but until value imports are available /// Morally, these are a value import, but until value imports are available
/// in the component model, this import function should return the same /// in the component model, this import function should return the same
/// values each time it is called. /// values each time it is called.
@since(version = 0.2.0)
get-environment: func() -> list<tuple<string, string>>; get-environment: func() -> list<tuple<string, string>>;
/// Get the POSIX-style arguments to the program. /// Get the POSIX-style arguments to the program.
@since(version = 0.2.0)
get-arguments: func() -> list<string>; get-arguments: func() -> list<string>;
/// Return a path that programs should use as their initial current working /// Return a path that programs should use as their initial current working
/// directory, interpreting `.` as shorthand for this. /// directory, interpreting `.` as shorthand for this.
@since(version = 0.2.0)
initial-cwd: func() -> option<string>; initial-cwd: func() -> option<string>;
} }

View File

@@ -1,4 +1,17 @@
@since(version = 0.2.0)
interface exit { interface exit {
/// Exit the current instance and any linked instances. /// Exit the current instance and any linked instances.
@since(version = 0.2.0)
exit: func(status: result); exit: func(status: result);
/// Exit the current instance and any linked instances, reporting the
/// specified status code to the host.
///
/// The meaning of the code depends on the context, with 0 usually meaning
/// "success", and other values indicating various types of failure.
///
/// This function does not return; the effect is analogous to a trap, but
/// without the connotation that something bad has happened.
@unstable(feature = cli-exit-with-code)
exit-with-code: func(status-code: u8);
} }

View File

@@ -1,20 +1,36 @@
package wasi:cli@0.2.0; package wasi:cli@0.2.4;
@since(version = 0.2.0)
world imports { world imports {
include wasi:clocks/imports@0.2.0; @since(version = 0.2.0)
include wasi:filesystem/imports@0.2.0; include wasi:clocks/imports@0.2.4;
include wasi:sockets/imports@0.2.0; @since(version = 0.2.0)
include wasi:random/imports@0.2.0; include wasi:filesystem/imports@0.2.4;
include wasi:io/imports@0.2.0; @since(version = 0.2.0)
include wasi:sockets/imports@0.2.4;
@since(version = 0.2.0)
include wasi:random/imports@0.2.4;
@since(version = 0.2.0)
include wasi:io/imports@0.2.4;
@since(version = 0.2.0)
import environment; import environment;
@since(version = 0.2.0)
import exit; import exit;
@since(version = 0.2.0)
import stdin; import stdin;
@since(version = 0.2.0)
import stdout; import stdout;
@since(version = 0.2.0)
import stderr; import stderr;
@since(version = 0.2.0)
import terminal-input; import terminal-input;
@since(version = 0.2.0)
import terminal-output; import terminal-output;
@since(version = 0.2.0)
import terminal-stdin; import terminal-stdin;
@since(version = 0.2.0)
import terminal-stdout; import terminal-stdout;
@since(version = 0.2.0)
import terminal-stderr; import terminal-stderr;
} }

View File

@@ -1,4 +1,6 @@
@since(version = 0.2.0)
interface run { interface run {
/// Run the program. /// Run the program.
@since(version = 0.2.0)
run: func() -> result; run: func() -> result;
} }

View File

@@ -1,17 +1,26 @@
@since(version = 0.2.0)
interface stdin { interface stdin {
use wasi:io/streams@0.2.0.{input-stream}; @since(version = 0.2.0)
use wasi:io/streams@0.2.4.{input-stream};
@since(version = 0.2.0)
get-stdin: func() -> input-stream; get-stdin: func() -> input-stream;
} }
@since(version = 0.2.0)
interface stdout { interface stdout {
use wasi:io/streams@0.2.0.{output-stream}; @since(version = 0.2.0)
use wasi:io/streams@0.2.4.{output-stream};
@since(version = 0.2.0)
get-stdout: func() -> output-stream; get-stdout: func() -> output-stream;
} }
@since(version = 0.2.0)
interface stderr { interface stderr {
use wasi:io/streams@0.2.0.{output-stream}; @since(version = 0.2.0)
use wasi:io/streams@0.2.4.{output-stream};
@since(version = 0.2.0)
get-stderr: func() -> output-stream; get-stderr: func() -> output-stream;
} }

View File

@@ -3,8 +3,10 @@
/// In the future, this may include functions for disabling echoing, /// In the future, this may include functions for disabling echoing,
/// disabling input buffering so that keyboard events are sent through /// disabling input buffering so that keyboard events are sent through
/// immediately, querying supported features, and so on. /// immediately, querying supported features, and so on.
@since(version = 0.2.0)
interface terminal-input { interface terminal-input {
/// The input side of a terminal. /// The input side of a terminal.
@since(version = 0.2.0)
resource terminal-input; resource terminal-input;
} }
@@ -13,37 +15,48 @@ interface terminal-input {
/// In the future, this may include functions for querying the terminal /// In the future, this may include functions for querying the terminal
/// size, being notified of terminal size changes, querying supported /// size, being notified of terminal size changes, querying supported
/// features, and so on. /// features, and so on.
@since(version = 0.2.0)
interface terminal-output { interface terminal-output {
/// The output side of a terminal. /// The output side of a terminal.
@since(version = 0.2.0)
resource terminal-output; resource terminal-output;
} }
/// An interface providing an optional `terminal-input` for stdin as a /// An interface providing an optional `terminal-input` for stdin as a
/// link-time authority. /// link-time authority.
@since(version = 0.2.0)
interface terminal-stdin { interface terminal-stdin {
@since(version = 0.2.0)
use terminal-input.{terminal-input}; use terminal-input.{terminal-input};
/// If stdin is connected to a terminal, return a `terminal-input` handle /// If stdin is connected to a terminal, return a `terminal-input` handle
/// allowing further interaction with it. /// allowing further interaction with it.
@since(version = 0.2.0)
get-terminal-stdin: func() -> option<terminal-input>; get-terminal-stdin: func() -> option<terminal-input>;
} }
/// An interface providing an optional `terminal-output` for stdout as a /// An interface providing an optional `terminal-output` for stdout as a
/// link-time authority. /// link-time authority.
@since(version = 0.2.0)
interface terminal-stdout { interface terminal-stdout {
@since(version = 0.2.0)
use terminal-output.{terminal-output}; use terminal-output.{terminal-output};
/// If stdout is connected to a terminal, return a `terminal-output` handle /// If stdout is connected to a terminal, return a `terminal-output` handle
/// allowing further interaction with it. /// allowing further interaction with it.
@since(version = 0.2.0)
get-terminal-stdout: func() -> option<terminal-output>; get-terminal-stdout: func() -> option<terminal-output>;
} }
/// An interface providing an optional `terminal-output` for stderr as a /// An interface providing an optional `terminal-output` for stderr as a
/// link-time authority. /// link-time authority.
@since(version = 0.2.0)
interface terminal-stderr { interface terminal-stderr {
@since(version = 0.2.0)
use terminal-output.{terminal-output}; use terminal-output.{terminal-output};
/// If stderr is connected to a terminal, return a `terminal-output` handle /// If stderr is connected to a terminal, return a `terminal-output` handle
/// allowing further interaction with it. /// allowing further interaction with it.
@since(version = 0.2.0)
get-terminal-stderr: func() -> option<terminal-output>; get-terminal-stderr: func() -> option<terminal-output>;
} }

View File

@@ -1,4 +1,4 @@
package wasi:clocks@0.2.0; package wasi:clocks@0.2.4;
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed /// WASI Monotonic Clock is a clock API intended to let users measure elapsed
/// time. /// time.
/// ///
@@ -7,38 +7,43 @@ package wasi:clocks@0.2.0;
/// ///
/// A monotonic clock is a clock which has an unspecified initial value, and /// A monotonic clock is a clock which has an unspecified initial value, and
/// successive reads of the clock will produce non-decreasing values. /// successive reads of the clock will produce non-decreasing values.
/// @since(version = 0.2.0)
/// It is intended for measuring elapsed time.
interface monotonic-clock { interface monotonic-clock {
use wasi:io/poll@0.2.0.{pollable}; @since(version = 0.2.0)
use wasi:io/poll@0.2.4.{pollable};
/// An instant in time, in nanoseconds. An instant is relative to an /// An instant in time, in nanoseconds. An instant is relative to an
/// unspecified initial value, and can only be compared to instances from /// unspecified initial value, and can only be compared to instances from
/// the same monotonic-clock. /// the same monotonic-clock.
@since(version = 0.2.0)
type instant = u64; type instant = u64;
/// A duration of time, in nanoseconds. /// A duration of time, in nanoseconds.
@since(version = 0.2.0)
type duration = u64; type duration = u64;
/// Read the current value of the clock. /// Read the current value of the clock.
/// ///
/// The clock is monotonic, therefore calling this function repeatedly will /// The clock is monotonic, therefore calling this function repeatedly will
/// produce a sequence of non-decreasing values. /// produce a sequence of non-decreasing values.
@since(version = 0.2.0)
now: func() -> instant; now: func() -> instant;
/// Query the resolution of the clock. Returns the duration of time /// Query the resolution of the clock. Returns the duration of time
/// corresponding to a clock tick. /// corresponding to a clock tick.
@since(version = 0.2.0)
resolution: func() -> duration; resolution: func() -> duration;
/// Create a `pollable` which will resolve once the specified instant /// Create a `pollable` which will resolve once the specified instant
/// occured. /// has occurred.
@since(version = 0.2.0)
subscribe-instant: func( subscribe-instant: func(
when: instant, when: instant,
) -> pollable; ) -> pollable;
/// Create a `pollable` which will resolve once the given duration has /// Create a `pollable` that will resolve after the specified duration has
/// elapsed, starting at the time at which this function was called. /// elapsed from the time this function is invoked.
/// occured. @since(version = 0.2.0)
subscribe-duration: func( subscribe-duration: func(
when: duration, when: duration,
) -> pollable; ) -> pollable;

View File

@@ -0,0 +1,55 @@
package wasi:clocks@0.2.4;
@unstable(feature = clocks-timezone)
interface timezone {
@unstable(feature = clocks-timezone)
use wall-clock.{datetime};
/// Return information needed to display the given `datetime`. This includes
/// the UTC offset, the time zone name, and a flag indicating whether
/// daylight saving time is active.
///
/// If the timezone cannot be determined for the given `datetime`, return a
/// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight
/// saving time.
@unstable(feature = clocks-timezone)
display: func(when: datetime) -> timezone-display;
/// The same as `display`, but only return the UTC offset.
@unstable(feature = clocks-timezone)
utc-offset: func(when: datetime) -> s32;
/// Information useful for displaying the timezone of a specific `datetime`.
///
/// This information may vary within a single `timezone` to reflect daylight
/// saving time adjustments.
@unstable(feature = clocks-timezone)
record timezone-display {
/// The number of seconds difference between UTC time and the local
/// time of the timezone.
///
/// The returned value will always be less than 86400 which is the
/// number of seconds in a day (24*60*60).
///
/// In implementations that do not expose an actual time zone, this
/// should return 0.
utc-offset: s32,
/// The abbreviated name of the timezone to display to a user. The name
/// `UTC` indicates Coordinated Universal Time. Otherwise, this should
/// reference local standards for the name of the time zone.
///
/// In implementations that do not expose an actual time zone, this
/// should be the string `UTC`.
///
/// In time zones that do not have an applicable name, a formatted
/// representation of the UTC offset may be returned, such as `-04:00`.
name: string,
/// Whether daylight saving time is active.
///
/// In implementations that do not expose an actual time zone, this
/// should return false.
in-daylight-saving-time: bool,
}
}

View File

@@ -1,4 +1,4 @@
package wasi:clocks@0.2.0; package wasi:clocks@0.2.4;
/// WASI Wall Clock is a clock API intended to let users query the current /// WASI Wall Clock is a clock API intended to let users query the current
/// time. The name "wall" makes an analogy to a "clock on the wall", which /// time. The name "wall" makes an analogy to a "clock on the wall", which
/// is not necessarily monotonic as it may be reset. /// is not necessarily monotonic as it may be reset.
@@ -13,8 +13,10 @@ package wasi:clocks@0.2.0;
/// monotonic, making it unsuitable for measuring elapsed time. /// monotonic, making it unsuitable for measuring elapsed time.
/// ///
/// It is intended for reporting the current date and time for humans. /// It is intended for reporting the current date and time for humans.
@since(version = 0.2.0)
interface wall-clock { interface wall-clock {
/// A time and date in seconds plus nanoseconds. /// A time and date in seconds plus nanoseconds.
@since(version = 0.2.0)
record datetime { record datetime {
seconds: u64, seconds: u64,
nanoseconds: u32, nanoseconds: u32,
@@ -33,10 +35,12 @@ interface wall-clock {
/// ///
/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16
/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time
@since(version = 0.2.0)
now: func() -> datetime; now: func() -> datetime;
/// Query the resolution of the clock. /// Query the resolution of the clock.
/// ///
/// The nanoseconds field of the output is always less than 1000000000. /// The nanoseconds field of the output is always less than 1000000000.
@since(version = 0.2.0)
resolution: func() -> datetime; resolution: func() -> datetime;
} }

View File

@@ -1,6 +1,11 @@
package wasi:clocks@0.2.0; package wasi:clocks@0.2.4;
@since(version = 0.2.0)
world imports { world imports {
@since(version = 0.2.0)
import monotonic-clock; import monotonic-clock;
@since(version = 0.2.0)
import wall-clock; import wall-clock;
@unstable(feature = clocks-timezone)
import timezone;
} }

View File

@@ -1,8 +1,11 @@
package wasi:filesystem@0.2.0; package wasi:filesystem@0.2.4;
@since(version = 0.2.0)
interface preopens { interface preopens {
@since(version = 0.2.0)
use types.{descriptor}; use types.{descriptor};
/// Return the set of preopened directories, and their path. /// Return the set of preopened directories, and their paths.
@since(version = 0.2.0)
get-directories: func() -> list<tuple<descriptor, string>>; get-directories: func() -> list<tuple<descriptor, string>>;
} }

View File

@@ -1,4 +1,4 @@
package wasi:filesystem@0.2.0; package wasi:filesystem@0.2.4;
/// WASI filesystem is a filesystem API primarily intended to let users run WASI /// WASI filesystem is a filesystem API primarily intended to let users run WASI
/// programs that access their files on their existing filesystems, without /// programs that access their files on their existing filesystems, without
/// significant overhead. /// significant overhead.
@@ -23,16 +23,21 @@ package wasi:filesystem@0.2.0;
/// [WASI filesystem path resolution]. /// [WASI filesystem path resolution].
/// ///
/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md /// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md
@since(version = 0.2.0)
interface types { interface types {
use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; @since(version = 0.2.0)
use wasi:clocks/wall-clock@0.2.0.{datetime}; use wasi:io/streams@0.2.4.{input-stream, output-stream, error};
@since(version = 0.2.0)
use wasi:clocks/wall-clock@0.2.4.{datetime};
/// File size or length of a region within a file. /// File size or length of a region within a file.
@since(version = 0.2.0)
type filesize = u64; type filesize = u64;
/// The type of a filesystem object referenced by a descriptor. /// The type of a filesystem object referenced by a descriptor.
/// ///
/// Note: This was called `filetype` in earlier versions of WASI. /// Note: This was called `filetype` in earlier versions of WASI.
@since(version = 0.2.0)
enum descriptor-type { enum descriptor-type {
/// The type of the descriptor or file is unknown or is different from /// The type of the descriptor or file is unknown or is different from
/// any of the other types specified. /// any of the other types specified.
@@ -56,6 +61,7 @@ interface types {
/// Descriptor flags. /// Descriptor flags.
/// ///
/// Note: This was called `fdflags` in earlier versions of WASI. /// Note: This was called `fdflags` in earlier versions of WASI.
@since(version = 0.2.0)
flags descriptor-flags { flags descriptor-flags {
/// Read mode: Data can be read. /// Read mode: Data can be read.
read, read,
@@ -77,7 +83,7 @@ interface types {
/// WASI. At this time, it should be interpreted as a request, and not a /// WASI. At this time, it should be interpreted as a request, and not a
/// requirement. /// requirement.
data-integrity-sync, data-integrity-sync,
/// Requests that reads be performed at the same level of integrety /// Requests that reads be performed at the same level of integrity
/// requested for writes. This is similar to `O_RSYNC` in POSIX. /// requested for writes. This is similar to `O_RSYNC` in POSIX.
/// ///
/// The precise semantics of this operation have not yet been defined for /// The precise semantics of this operation have not yet been defined for
@@ -99,6 +105,7 @@ interface types {
/// File attributes. /// File attributes.
/// ///
/// Note: This was called `filestat` in earlier versions of WASI. /// Note: This was called `filestat` in earlier versions of WASI.
@since(version = 0.2.0)
record descriptor-stat { record descriptor-stat {
/// File type. /// File type.
%type: descriptor-type, %type: descriptor-type,
@@ -125,6 +132,7 @@ interface types {
} }
/// Flags determining the method of how paths are resolved. /// Flags determining the method of how paths are resolved.
@since(version = 0.2.0)
flags path-flags { flags path-flags {
/// As long as the resolved path corresponds to a symbolic link, it is /// As long as the resolved path corresponds to a symbolic link, it is
/// expanded. /// expanded.
@@ -132,6 +140,7 @@ interface types {
} }
/// Open flags used by `open-at`. /// Open flags used by `open-at`.
@since(version = 0.2.0)
flags open-flags { flags open-flags {
/// Create file if it does not exist, similar to `O_CREAT` in POSIX. /// Create file if it does not exist, similar to `O_CREAT` in POSIX.
create, create,
@@ -144,9 +153,11 @@ interface types {
} }
/// Number of hard links to an inode. /// Number of hard links to an inode.
@since(version = 0.2.0)
type link-count = u64; type link-count = u64;
/// When setting a timestamp, this gives the value to set it to. /// When setting a timestamp, this gives the value to set it to.
@since(version = 0.2.0)
variant new-timestamp { variant new-timestamp {
/// Leave the timestamp set to its previous value. /// Leave the timestamp set to its previous value.
no-change, no-change,
@@ -248,6 +259,7 @@ interface types {
} }
/// File or memory access pattern advisory information. /// File or memory access pattern advisory information.
@since(version = 0.2.0)
enum advice { enum advice {
/// The application has no advice to give on its behavior with respect /// The application has no advice to give on its behavior with respect
/// to the specified data. /// to the specified data.
@@ -271,6 +283,7 @@ interface types {
/// A 128-bit hash value, split into parts because wasm doesn't have a /// A 128-bit hash value, split into parts because wasm doesn't have a
/// 128-bit integer type. /// 128-bit integer type.
@since(version = 0.2.0)
record metadata-hash-value { record metadata-hash-value {
/// 64 bits of a 128-bit hash value. /// 64 bits of a 128-bit hash value.
lower: u64, lower: u64,
@@ -281,6 +294,7 @@ interface types {
/// A descriptor is a reference to a filesystem object, which may be a file, /// A descriptor is a reference to a filesystem object, which may be a file,
/// directory, named pipe, special file, or other object on which filesystem /// directory, named pipe, special file, or other object on which filesystem
/// calls may be made. /// calls may be made.
@since(version = 0.2.0)
resource descriptor { resource descriptor {
/// Return a stream for reading from a file, if available. /// Return a stream for reading from a file, if available.
/// ///
@@ -290,6 +304,7 @@ interface types {
/// file and they do not interfere with each other. /// file and they do not interfere with each other.
/// ///
/// Note: This allows using `read-stream`, which is similar to `read` in POSIX. /// Note: This allows using `read-stream`, which is similar to `read` in POSIX.
@since(version = 0.2.0)
read-via-stream: func( read-via-stream: func(
/// The offset within the file at which to start reading. /// The offset within the file at which to start reading.
offset: filesize, offset: filesize,
@@ -301,6 +316,7 @@ interface types {
/// ///
/// Note: This allows using `write-stream`, which is similar to `write` in /// Note: This allows using `write-stream`, which is similar to `write` in
/// POSIX. /// POSIX.
@since(version = 0.2.0)
write-via-stream: func( write-via-stream: func(
/// The offset within the file at which to start writing. /// The offset within the file at which to start writing.
offset: filesize, offset: filesize,
@@ -311,12 +327,14 @@ interface types {
/// May fail with an error-code describing why the file cannot be appended. /// May fail with an error-code describing why the file cannot be appended.
/// ///
/// Note: This allows using `write-stream`, which is similar to `write` with /// Note: This allows using `write-stream`, which is similar to `write` with
/// `O_APPEND` in in POSIX. /// `O_APPEND` in POSIX.
@since(version = 0.2.0)
append-via-stream: func() -> result<output-stream, error-code>; append-via-stream: func() -> result<output-stream, error-code>;
/// Provide file advisory information on a descriptor. /// Provide file advisory information on a descriptor.
/// ///
/// This is similar to `posix_fadvise` in POSIX. /// This is similar to `posix_fadvise` in POSIX.
@since(version = 0.2.0)
advise: func( advise: func(
/// The offset within the file to which the advisory applies. /// The offset within the file to which the advisory applies.
offset: filesize, offset: filesize,
@@ -332,6 +350,7 @@ interface types {
/// opened for writing. /// opened for writing.
/// ///
/// Note: This is similar to `fdatasync` in POSIX. /// Note: This is similar to `fdatasync` in POSIX.
@since(version = 0.2.0)
sync-data: func() -> result<_, error-code>; sync-data: func() -> result<_, error-code>;
/// Get flags associated with a descriptor. /// Get flags associated with a descriptor.
@@ -340,6 +359,7 @@ interface types {
/// ///
/// Note: This returns the value that was the `fs_flags` value returned /// Note: This returns the value that was the `fs_flags` value returned
/// from `fdstat_get` in earlier versions of WASI. /// from `fdstat_get` in earlier versions of WASI.
@since(version = 0.2.0)
get-flags: func() -> result<descriptor-flags, error-code>; get-flags: func() -> result<descriptor-flags, error-code>;
/// Get the dynamic type of a descriptor. /// Get the dynamic type of a descriptor.
@@ -352,12 +372,14 @@ interface types {
/// ///
/// Note: This returns the value that was the `fs_filetype` value returned /// Note: This returns the value that was the `fs_filetype` value returned
/// from `fdstat_get` in earlier versions of WASI. /// from `fdstat_get` in earlier versions of WASI.
@since(version = 0.2.0)
get-type: func() -> result<descriptor-type, error-code>; get-type: func() -> result<descriptor-type, error-code>;
/// Adjust the size of an open file. If this increases the file's size, the /// Adjust the size of an open file. If this increases the file's size, the
/// extra bytes are filled with zeros. /// extra bytes are filled with zeros.
/// ///
/// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI.
@since(version = 0.2.0)
set-size: func(size: filesize) -> result<_, error-code>; set-size: func(size: filesize) -> result<_, error-code>;
/// Adjust the timestamps of an open file or directory. /// Adjust the timestamps of an open file or directory.
@@ -365,6 +387,7 @@ interface types {
/// Note: This is similar to `futimens` in POSIX. /// Note: This is similar to `futimens` in POSIX.
/// ///
/// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI.
@since(version = 0.2.0)
set-times: func( set-times: func(
/// The desired values of the data access timestamp. /// The desired values of the data access timestamp.
data-access-timestamp: new-timestamp, data-access-timestamp: new-timestamp,
@@ -383,6 +406,7 @@ interface types {
/// In the future, this may change to return a `stream<u8, error-code>`. /// In the future, this may change to return a `stream<u8, error-code>`.
/// ///
/// Note: This is similar to `pread` in POSIX. /// Note: This is similar to `pread` in POSIX.
@since(version = 0.2.0)
read: func( read: func(
/// The maximum number of bytes to read. /// The maximum number of bytes to read.
length: filesize, length: filesize,
@@ -399,6 +423,7 @@ interface types {
/// In the future, this may change to take a `stream<u8, error-code>`. /// In the future, this may change to take a `stream<u8, error-code>`.
/// ///
/// Note: This is similar to `pwrite` in POSIX. /// Note: This is similar to `pwrite` in POSIX.
@since(version = 0.2.0)
write: func( write: func(
/// Data to write /// Data to write
buffer: list<u8>, buffer: list<u8>,
@@ -415,6 +440,7 @@ interface types {
/// This always returns a new stream which starts at the beginning of the /// This always returns a new stream which starts at the beginning of the
/// directory. Multiple streams may be active on the same directory, and they /// directory. Multiple streams may be active on the same directory, and they
/// do not interfere with each other. /// do not interfere with each other.
@since(version = 0.2.0)
read-directory: func() -> result<directory-entry-stream, error-code>; read-directory: func() -> result<directory-entry-stream, error-code>;
/// Synchronize the data and metadata of a file to disk. /// Synchronize the data and metadata of a file to disk.
@@ -423,11 +449,13 @@ interface types {
/// opened for writing. /// opened for writing.
/// ///
/// Note: This is similar to `fsync` in POSIX. /// Note: This is similar to `fsync` in POSIX.
@since(version = 0.2.0)
sync: func() -> result<_, error-code>; sync: func() -> result<_, error-code>;
/// Create a directory. /// Create a directory.
/// ///
/// Note: This is similar to `mkdirat` in POSIX. /// Note: This is similar to `mkdirat` in POSIX.
@since(version = 0.2.0)
create-directory-at: func( create-directory-at: func(
/// The relative path at which to create the directory. /// The relative path at which to create the directory.
path: string, path: string,
@@ -442,6 +470,7 @@ interface types {
/// modified, use `metadata-hash`. /// modified, use `metadata-hash`.
/// ///
/// Note: This was called `fd_filestat_get` in earlier versions of WASI. /// Note: This was called `fd_filestat_get` in earlier versions of WASI.
@since(version = 0.2.0)
stat: func() -> result<descriptor-stat, error-code>; stat: func() -> result<descriptor-stat, error-code>;
/// Return the attributes of a file or directory. /// Return the attributes of a file or directory.
@@ -451,6 +480,7 @@ interface types {
/// discussion of alternatives. /// discussion of alternatives.
/// ///
/// Note: This was called `path_filestat_get` in earlier versions of WASI. /// Note: This was called `path_filestat_get` in earlier versions of WASI.
@since(version = 0.2.0)
stat-at: func( stat-at: func(
/// Flags determining the method of how the path is resolved. /// Flags determining the method of how the path is resolved.
path-flags: path-flags, path-flags: path-flags,
@@ -464,6 +494,7 @@ interface types {
/// ///
/// Note: This was called `path_filestat_set_times` in earlier versions of /// Note: This was called `path_filestat_set_times` in earlier versions of
/// WASI. /// WASI.
@since(version = 0.2.0)
set-times-at: func( set-times-at: func(
/// Flags determining the method of how the path is resolved. /// Flags determining the method of how the path is resolved.
path-flags: path-flags, path-flags: path-flags,
@@ -477,7 +508,12 @@ interface types {
/// Create a hard link. /// Create a hard link.
/// ///
/// Fails with `error-code::no-entry` if the old path does not exist,
/// with `error-code::exist` if the new path already exists, and
/// `error-code::not-permitted` if the old path is not a file.
///
/// Note: This is similar to `linkat` in POSIX. /// Note: This is similar to `linkat` in POSIX.
@since(version = 0.2.0)
link-at: func( link-at: func(
/// Flags determining the method of how the path is resolved. /// Flags determining the method of how the path is resolved.
old-path-flags: path-flags, old-path-flags: path-flags,
@@ -491,12 +527,6 @@ interface types {
/// Open a file or directory. /// Open a file or directory.
/// ///
/// The returned descriptor is not guaranteed to be the lowest-numbered
/// descriptor not currently open/ it is randomized to prevent applications
/// from depending on making assumptions about indexes, since this is
/// error-prone in multi-threaded contexts. The returned descriptor is
/// guaranteed to be less than 2**31.
///
/// If `flags` contains `descriptor-flags::mutate-directory`, and the base /// If `flags` contains `descriptor-flags::mutate-directory`, and the base
/// descriptor doesn't have `descriptor-flags::mutate-directory` set, /// descriptor doesn't have `descriptor-flags::mutate-directory` set,
/// `open-at` fails with `error-code::read-only`. /// `open-at` fails with `error-code::read-only`.
@@ -507,6 +537,7 @@ interface types {
/// `error-code::read-only`. /// `error-code::read-only`.
/// ///
/// Note: This is similar to `openat` in POSIX. /// Note: This is similar to `openat` in POSIX.
@since(version = 0.2.0)
open-at: func( open-at: func(
/// Flags determining the method of how the path is resolved. /// Flags determining the method of how the path is resolved.
path-flags: path-flags, path-flags: path-flags,
@@ -524,6 +555,7 @@ interface types {
/// filesystem, this function fails with `error-code::not-permitted`. /// filesystem, this function fails with `error-code::not-permitted`.
/// ///
/// Note: This is similar to `readlinkat` in POSIX. /// Note: This is similar to `readlinkat` in POSIX.
@since(version = 0.2.0)
readlink-at: func( readlink-at: func(
/// The relative path of the symbolic link from which to read. /// The relative path of the symbolic link from which to read.
path: string, path: string,
@@ -534,6 +566,7 @@ interface types {
/// Return `error-code::not-empty` if the directory is not empty. /// Return `error-code::not-empty` if the directory is not empty.
/// ///
/// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX.
@since(version = 0.2.0)
remove-directory-at: func( remove-directory-at: func(
/// The relative path to a directory to remove. /// The relative path to a directory to remove.
path: string, path: string,
@@ -542,6 +575,7 @@ interface types {
/// Rename a filesystem object. /// Rename a filesystem object.
/// ///
/// Note: This is similar to `renameat` in POSIX. /// Note: This is similar to `renameat` in POSIX.
@since(version = 0.2.0)
rename-at: func( rename-at: func(
/// The relative source path of the file or directory to rename. /// The relative source path of the file or directory to rename.
old-path: string, old-path: string,
@@ -557,6 +591,7 @@ interface types {
/// `error-code::not-permitted`. /// `error-code::not-permitted`.
/// ///
/// Note: This is similar to `symlinkat` in POSIX. /// Note: This is similar to `symlinkat` in POSIX.
@since(version = 0.2.0)
symlink-at: func( symlink-at: func(
/// The contents of the symbolic link. /// The contents of the symbolic link.
old-path: string, old-path: string,
@@ -568,6 +603,7 @@ interface types {
/// ///
/// Return `error-code::is-directory` if the path refers to a directory. /// Return `error-code::is-directory` if the path refers to a directory.
/// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX.
@since(version = 0.2.0)
unlink-file-at: func( unlink-file-at: func(
/// The relative path to a file to unlink. /// The relative path to a file to unlink.
path: string, path: string,
@@ -579,6 +615,7 @@ interface types {
/// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers.
/// wasi-filesystem does not expose device and inode numbers, so this function /// wasi-filesystem does not expose device and inode numbers, so this function
/// may be used instead. /// may be used instead.
@since(version = 0.2.0)
is-same-object: func(other: borrow<descriptor>) -> bool; is-same-object: func(other: borrow<descriptor>) -> bool;
/// Return a hash of the metadata associated with a filesystem object referred /// Return a hash of the metadata associated with a filesystem object referred
@@ -590,7 +627,7 @@ interface types {
/// replaced. It may also include a secret value chosen by the /// replaced. It may also include a secret value chosen by the
/// implementation and not otherwise exposed. /// implementation and not otherwise exposed.
/// ///
/// Implementations are encourated to provide the following properties: /// Implementations are encouraged to provide the following properties:
/// ///
/// - If the file is not modified or replaced, the computed hash value should /// - If the file is not modified or replaced, the computed hash value should
/// usually not change. /// usually not change.
@@ -600,12 +637,14 @@ interface types {
/// computed hash. /// computed hash.
/// ///
/// However, none of these is required. /// However, none of these is required.
@since(version = 0.2.0)
metadata-hash: func() -> result<metadata-hash-value, error-code>; metadata-hash: func() -> result<metadata-hash-value, error-code>;
/// Return a hash of the metadata associated with a filesystem object referred /// Return a hash of the metadata associated with a filesystem object referred
/// to by a directory descriptor and a relative path. /// to by a directory descriptor and a relative path.
/// ///
/// This performs the same hash computation as `metadata-hash`. /// This performs the same hash computation as `metadata-hash`.
@since(version = 0.2.0)
metadata-hash-at: func( metadata-hash-at: func(
/// Flags determining the method of how the path is resolved. /// Flags determining the method of how the path is resolved.
path-flags: path-flags, path-flags: path-flags,
@@ -615,8 +654,10 @@ interface types {
} }
/// A stream of directory entries. /// A stream of directory entries.
@since(version = 0.2.0)
resource directory-entry-stream { resource directory-entry-stream {
/// Read a single directory entry from a `directory-entry-stream`. /// Read a single directory entry from a `directory-entry-stream`.
@since(version = 0.2.0)
read-directory-entry: func() -> result<option<directory-entry>, error-code>; read-directory-entry: func() -> result<option<directory-entry>, error-code>;
} }
@@ -630,5 +671,6 @@ interface types {
/// ///
/// Note that this function is fallible because not all stream-related /// Note that this function is fallible because not all stream-related
/// errors are filesystem-related errors. /// errors are filesystem-related errors.
@since(version = 0.2.0)
filesystem-error-code: func(err: borrow<error>) -> option<error-code>; filesystem-error-code: func(err: borrow<error>) -> option<error-code>;
} }

View File

@@ -1,6 +1,9 @@
package wasi:filesystem@0.2.0; package wasi:filesystem@0.2.4;
@since(version = 0.2.0)
world imports { world imports {
@since(version = 0.2.0)
import types; import types;
@since(version = 0.2.0)
import preopens; import preopens;
} }

View File

@@ -1,6 +1,8 @@
/// This interface defines a handler of incoming HTTP Requests. It should /// This interface defines a handler of incoming HTTP Requests. It should
/// be exported by components which can respond to HTTP Requests. /// be exported by components which can respond to HTTP Requests.
@since(version = 0.2.0)
interface incoming-handler { interface incoming-handler {
@since(version = 0.2.0)
use types.{incoming-request, response-outparam}; use types.{incoming-request, response-outparam};
/// This function is invoked with an incoming HTTP Request, and a resource /// This function is invoked with an incoming HTTP Request, and a resource
@@ -13,6 +15,7 @@ interface incoming-handler {
/// The implementor of this function must write a response to the /// The implementor of this function must write a response to the
/// `response-outparam` before returning, or else the caller will respond /// `response-outparam` before returning, or else the caller will respond
/// with an error on its behalf. /// with an error on its behalf.
@since(version = 0.2.0)
handle: func( handle: func(
request: incoming-request, request: incoming-request,
response-out: response-outparam response-out: response-outparam
@@ -21,7 +24,9 @@ interface incoming-handler {
/// This interface defines a handler of outgoing HTTP Requests. It should be /// This interface defines a handler of outgoing HTTP Requests. It should be
/// imported by components which wish to make HTTP Requests. /// imported by components which wish to make HTTP Requests.
@since(version = 0.2.0)
interface outgoing-handler { interface outgoing-handler {
@since(version = 0.2.0)
use types.{ use types.{
outgoing-request, request-options, future-incoming-response, error-code outgoing-request, request-options, future-incoming-response, error-code
}; };
@@ -36,6 +41,7 @@ interface outgoing-handler {
/// This function may return an error if the `outgoing-request` is invalid /// This function may return an error if the `outgoing-request` is invalid
/// or not allowed to be made. Otherwise, protocol errors are reported /// or not allowed to be made. Otherwise, protocol errors are reported
/// through the `future-incoming-response`. /// through the `future-incoming-response`.
@since(version = 0.2.0)
handle: func( handle: func(
request: outgoing-request, request: outgoing-request,
options: option<request-options> options: option<request-options>

View File

@@ -1,32 +1,50 @@
package wasi:http@0.2.0; package wasi:http@0.2.4;
/// The `wasi:http/proxy` world captures a widely-implementable intersection of /// The `wasi:http/imports` world imports all the APIs for HTTP proxies.
/// hosts that includes HTTP forward and reverse proxies. Components targeting /// It is intended to be `include`d in other worlds.
/// this world may concurrently stream in and out any number of incoming and @since(version = 0.2.0)
/// outgoing HTTP requests. world imports {
world proxy {
/// HTTP proxies have access to time and randomness. /// HTTP proxies have access to time and randomness.
include wasi:clocks/imports@0.2.0; @since(version = 0.2.0)
import wasi:random/random@0.2.0; import wasi:clocks/monotonic-clock@0.2.4;
@since(version = 0.2.0)
import wasi:clocks/wall-clock@0.2.4;
@since(version = 0.2.0)
import wasi:random/random@0.2.4;
/// Proxies have standard output and error streams which are expected to /// Proxies have standard output and error streams which are expected to
/// terminate in a developer-facing console provided by the host. /// terminate in a developer-facing console provided by the host.
import wasi:cli/stdout@0.2.0; @since(version = 0.2.0)
import wasi:cli/stderr@0.2.0; import wasi:cli/stdout@0.2.4;
@since(version = 0.2.0)
import wasi:cli/stderr@0.2.4;
/// TODO: this is a temporary workaround until component tooling is able to /// TODO: this is a temporary workaround until component tooling is able to
/// gracefully handle the absence of stdin. Hosts must return an eof stream /// gracefully handle the absence of stdin. Hosts must return an eof stream
/// for this import, which is what wasi-libc + tooling will do automatically /// for this import, which is what wasi-libc + tooling will do automatically
/// when this import is properly removed. /// when this import is properly removed.
import wasi:cli/stdin@0.2.0; @since(version = 0.2.0)
import wasi:cli/stdin@0.2.4;
/// This is the default handler to use when user code simply wants to make an /// This is the default handler to use when user code simply wants to make an
/// HTTP request (e.g., via `fetch()`). /// HTTP request (e.g., via `fetch()`).
@since(version = 0.2.0)
import outgoing-handler; import outgoing-handler;
}
/// The `wasi:http/proxy` world captures a widely-implementable intersection of
/// hosts that includes HTTP forward and reverse proxies. Components targeting
/// this world may concurrently stream in and out any number of incoming and
/// outgoing HTTP requests.
@since(version = 0.2.0)
world proxy {
@since(version = 0.2.0)
include imports;
/// The host delivers incoming HTTP requests to a component by calling the /// The host delivers incoming HTTP requests to a component by calling the
/// `handle` function of this exported interface. A host may arbitrarily reuse /// `handle` function of this exported interface. A host may arbitrarily reuse
/// or not reuse component instance when delivering incoming HTTP requests and /// or not reuse component instance when delivering incoming HTTP requests and
/// thus a component must be able to handle 0..N calls to `handle`. /// thus a component must be able to handle 0..N calls to `handle`.
@since(version = 0.2.0)
export incoming-handler; export incoming-handler;
} }

View File

@@ -1,13 +1,19 @@
/// This interface defines all of the types and methods for implementing /// This interface defines all of the types and methods for implementing
/// HTTP Requests and Responses, both incoming and outgoing, as well as /// HTTP Requests and Responses, both incoming and outgoing, as well as
/// their headers, trailers, and bodies. /// their headers, trailers, and bodies.
@since(version = 0.2.0)
interface types { interface types {
use wasi:clocks/monotonic-clock@0.2.0.{duration}; @since(version = 0.2.0)
use wasi:io/streams@0.2.0.{input-stream, output-stream}; use wasi:clocks/monotonic-clock@0.2.4.{duration};
use wasi:io/error@0.2.0.{error as io-error}; @since(version = 0.2.0)
use wasi:io/poll@0.2.0.{pollable}; use wasi:io/streams@0.2.4.{input-stream, output-stream};
@since(version = 0.2.0)
use wasi:io/error@0.2.4.{error as io-error};
@since(version = 0.2.0)
use wasi:io/poll@0.2.4.{pollable};
/// This type corresponds to HTTP standard Methods. /// This type corresponds to HTTP standard Methods.
@since(version = 0.2.0)
variant method { variant method {
get, get,
head, head,
@@ -22,6 +28,7 @@ interface types {
} }
/// This type corresponds to HTTP standard Related Schemes. /// This type corresponds to HTTP standard Related Schemes.
@since(version = 0.2.0)
variant scheme { variant scheme {
HTTP, HTTP,
HTTPS, HTTPS,
@@ -29,7 +36,8 @@ interface types {
} }
/// These cases are inspired by the IANA HTTP Proxy Error Types: /// These cases are inspired by the IANA HTTP Proxy Error Types:
/// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types /// <https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types>
@since(version = 0.2.0)
variant error-code { variant error-code {
DNS-timeout, DNS-timeout,
DNS-error(DNS-error-payload), DNS-error(DNS-error-payload),
@@ -78,18 +86,21 @@ interface types {
} }
/// Defines the case payload type for `DNS-error` above: /// Defines the case payload type for `DNS-error` above:
@since(version = 0.2.0)
record DNS-error-payload { record DNS-error-payload {
rcode: option<string>, rcode: option<string>,
info-code: option<u16> info-code: option<u16>
} }
/// Defines the case payload type for `TLS-alert-received` above: /// Defines the case payload type for `TLS-alert-received` above:
@since(version = 0.2.0)
record TLS-alert-received-payload { record TLS-alert-received-payload {
alert-id: option<u8>, alert-id: option<u8>,
alert-message: option<string> alert-message: option<string>
} }
/// Defines the case payload type for `HTTP-response-{header,trailer}-size` above: /// Defines the case payload type for `HTTP-response-{header,trailer}-size` above:
@since(version = 0.2.0)
record field-size-payload { record field-size-payload {
field-name: option<string>, field-name: option<string>,
field-size: option<u32> field-size: option<u32>
@@ -106,17 +117,19 @@ interface types {
/// ///
/// Note that this function is fallible because not all io-errors are /// Note that this function is fallible because not all io-errors are
/// http-related errors. /// http-related errors.
@since(version = 0.2.0)
http-error-code: func(err: borrow<io-error>) -> option<error-code>; http-error-code: func(err: borrow<io-error>) -> option<error-code>;
/// This type enumerates the different kinds of errors that may occur when /// This type enumerates the different kinds of errors that may occur when
/// setting or appending to a `fields` resource. /// setting or appending to a `fields` resource.
@since(version = 0.2.0)
variant header-error { variant header-error {
/// This error indicates that a `field-key` or `field-value` was /// This error indicates that a `field-name` or `field-value` was
/// syntactically invalid when used with an operation that sets headers in a /// syntactically invalid when used with an operation that sets headers in a
/// `fields`. /// `fields`.
invalid-syntax, invalid-syntax,
/// This error indicates that a forbidden `field-key` was used when trying /// This error indicates that a forbidden `field-name` was used when trying
/// to set a header in a `fields`. /// to set a header in a `fields`.
forbidden, forbidden,
@@ -125,12 +138,29 @@ interface types {
immutable, immutable,
} }
/// Field names are always strings.
///
/// Field names should always be treated as case insensitive by the `fields`
/// resource for the purposes of equality checking.
@since(version = 0.2.1)
type field-name = field-key;
/// Field keys are always strings. /// Field keys are always strings.
///
/// Field keys should always be treated as case insensitive by the `fields`
/// resource for the purposes of equality checking.
///
/// # Deprecation
///
/// This type has been deprecated in favor of the `field-name` type.
@since(version = 0.2.0)
@deprecated(version = 0.2.2)
type field-key = string; type field-key = string;
/// Field values should always be ASCII strings. However, in /// Field values should always be ASCII strings. However, in
/// reality, HTTP implementations often have to interpret malformed values, /// reality, HTTP implementations often have to interpret malformed values,
/// so they are provided as a list of bytes. /// so they are provided as a list of bytes.
@since(version = 0.2.0)
type field-value = list<u8>; type field-value = list<u8>;
/// This following block defines the `fields` resource which corresponds to /// This following block defines the `fields` resource which corresponds to
@@ -140,96 +170,123 @@ interface types {
/// A `fields` may be mutable or immutable. A `fields` created using the /// A `fields` may be mutable or immutable. A `fields` created using the
/// constructor, `from-list`, or `clone` will be mutable, but a `fields` /// constructor, `from-list`, or `clone` will be mutable, but a `fields`
/// resource given by other means (including, but not limited to, /// resource given by other means (including, but not limited to,
/// `incoming-request.headers`, `outgoing-request.headers`) might be be /// `incoming-request.headers`, `outgoing-request.headers`) might be
/// immutable. In an immutable fields, the `set`, `append`, and `delete` /// immutable. In an immutable fields, the `set`, `append`, and `delete`
/// operations will fail with `header-error.immutable`. /// operations will fail with `header-error.immutable`.
@since(version = 0.2.0)
resource fields { resource fields {
/// Construct an empty HTTP Fields. /// Construct an empty HTTP Fields.
/// ///
/// The resulting `fields` is mutable. /// The resulting `fields` is mutable.
@since(version = 0.2.0)
constructor(); constructor();
/// Construct an HTTP Fields. /// Construct an HTTP Fields.
/// ///
/// The resulting `fields` is mutable. /// The resulting `fields` is mutable.
/// ///
/// The list represents each key-value pair in the Fields. Keys /// The list represents each name-value pair in the Fields. Names
/// which have multiple values are represented by multiple entries in this /// which have multiple values are represented by multiple entries in this
/// list with the same key. /// list with the same name.
/// ///
/// The tuple is a pair of the field key, represented as a string, and /// The tuple is a pair of the field name, represented as a string, and
/// Value, represented as a list of bytes. In a valid Fields, all keys /// Value, represented as a list of bytes.
/// and values are valid UTF-8 strings. However, values are not always
/// well-formed, so they are represented as a raw list of bytes.
/// ///
/// An error result will be returned if any header or value was /// An error result will be returned if any `field-name` or `field-value` is
/// syntactically invalid, or if a header was forbidden. /// syntactically invalid, or if a field is forbidden.
@since(version = 0.2.0)
from-list: static func( from-list: static func(
entries: list<tuple<field-key,field-value>> entries: list<tuple<field-name,field-value>>
) -> result<fields, header-error>; ) -> result<fields, header-error>;
/// Get all of the values corresponding to a key. If the key is not present /// Get all of the values corresponding to a name. If the name is not present
/// in this `fields`, an empty list is returned. However, if the key is /// in this `fields` or is syntactically invalid, an empty list is returned.
/// present but empty, this is represented by a list with one or more /// However, if the name is present but empty, this is represented by a list
/// empty field-values present. /// with one or more empty field-values present.
get: func(name: field-key) -> list<field-value>; @since(version = 0.2.0)
get: func(name: field-name) -> list<field-value>;
/// Returns `true` when the key is present in this `fields`. If the key is /// Returns `true` when the name is present in this `fields`. If the name is
/// syntactically invalid, `false` is returned. /// syntactically invalid, `false` is returned.
has: func(name: field-key) -> bool; @since(version = 0.2.0)
has: func(name: field-name) -> bool;
/// Set all of the values for a key. Clears any existing values for that /// Set all of the values for a name. Clears any existing values for that
/// key, if they have been set. /// name, if they have been set.
/// ///
/// Fails with `header-error.immutable` if the `fields` are immutable. /// Fails with `header-error.immutable` if the `fields` are immutable.
set: func(name: field-key, value: list<field-value>) -> result<_, header-error>; ///
/// Fails with `header-error.invalid-syntax` if the `field-name` or any of
/// the `field-value`s are syntactically invalid.
@since(version = 0.2.0)
set: func(name: field-name, value: list<field-value>) -> result<_, header-error>;
/// Delete all values for a key. Does nothing if no values for the key /// Delete all values for a name. Does nothing if no values for the name
/// exist. /// exist.
/// ///
/// Fails with `header-error.immutable` if the `fields` are immutable. /// Fails with `header-error.immutable` if the `fields` are immutable.
delete: func(name: field-key) -> result<_, header-error>; ///
/// Fails with `header-error.invalid-syntax` if the `field-name` is
/// syntactically invalid.
@since(version = 0.2.0)
delete: func(name: field-name) -> result<_, header-error>;
/// Append a value for a key. Does not change or delete any existing /// Append a value for a name. Does not change or delete any existing
/// values for that key. /// values for that name.
/// ///
/// Fails with `header-error.immutable` if the `fields` are immutable. /// Fails with `header-error.immutable` if the `fields` are immutable.
append: func(name: field-key, value: field-value) -> result<_, header-error>;
/// Retrieve the full set of keys and values in the Fields. Like the
/// constructor, the list represents each key-value pair.
/// ///
/// The outer list represents each key-value pair in the Fields. Keys /// Fails with `header-error.invalid-syntax` if the `field-name` or
/// which have multiple values are represented by multiple entries in this /// `field-value` are syntactically invalid.
/// list with the same key. @since(version = 0.2.0)
entries: func() -> list<tuple<field-key,field-value>>; append: func(name: field-name, value: field-value) -> result<_, header-error>;
/// Make a deep copy of the Fields. Equivelant in behavior to calling the /// Retrieve the full set of names and values in the Fields. Like the
/// constructor, the list represents each name-value pair.
///
/// The outer list represents each name-value pair in the Fields. Names
/// which have multiple values are represented by multiple entries in this
/// list with the same name.
///
/// The names and values are always returned in the original casing and in
/// the order in which they will be serialized for transport.
@since(version = 0.2.0)
entries: func() -> list<tuple<field-name,field-value>>;
/// Make a deep copy of the Fields. Equivalent in behavior to calling the
/// `fields` constructor on the return value of `entries`. The resulting /// `fields` constructor on the return value of `entries`. The resulting
/// `fields` is mutable. /// `fields` is mutable.
@since(version = 0.2.0)
clone: func() -> fields; clone: func() -> fields;
} }
/// Headers is an alias for Fields. /// Headers is an alias for Fields.
@since(version = 0.2.0)
type headers = fields; type headers = fields;
/// Trailers is an alias for Fields. /// Trailers is an alias for Fields.
@since(version = 0.2.0)
type trailers = fields; type trailers = fields;
/// Represents an incoming HTTP Request. /// Represents an incoming HTTP Request.
@since(version = 0.2.0)
resource incoming-request { resource incoming-request {
/// Returns the method of the incoming request. /// Returns the method of the incoming request.
@since(version = 0.2.0)
method: func() -> method; method: func() -> method;
/// Returns the path with query parameters from the request, as a string. /// Returns the path with query parameters from the request, as a string.
@since(version = 0.2.0)
path-with-query: func() -> option<string>; path-with-query: func() -> option<string>;
/// Returns the protocol scheme from the request. /// Returns the protocol scheme from the request.
@since(version = 0.2.0)
scheme: func() -> option<scheme>; scheme: func() -> option<scheme>;
/// Returns the authority from the request, if it was present. /// Returns the authority of the Request's target URI, if present.
@since(version = 0.2.0)
authority: func() -> option<string>; authority: func() -> option<string>;
/// Get the `headers` associated with the request. /// Get the `headers` associated with the request.
@@ -240,14 +297,17 @@ interface types {
/// The `headers` returned are a child resource: it must be dropped before /// The `headers` returned are a child resource: it must be dropped before
/// the parent `incoming-request` is dropped. Dropping this /// the parent `incoming-request` is dropped. Dropping this
/// `incoming-request` before all children are dropped will trap. /// `incoming-request` before all children are dropped will trap.
@since(version = 0.2.0)
headers: func() -> headers; headers: func() -> headers;
/// Gives the `incoming-body` associated with this request. Will only /// Gives the `incoming-body` associated with this request. Will only
/// return success at most once, and subsequent calls will return error. /// return success at most once, and subsequent calls will return error.
@since(version = 0.2.0)
consume: func() -> result<incoming-body>; consume: func() -> result<incoming-body>;
} }
/// Represents an outgoing HTTP Request. /// Represents an outgoing HTTP Request.
@since(version = 0.2.0)
resource outgoing-request { resource outgoing-request {
/// Construct a new `outgoing-request` with a default `method` of `GET`, and /// Construct a new `outgoing-request` with a default `method` of `GET`, and
@@ -260,6 +320,7 @@ interface types {
/// and `authority`, or `headers` which are not permitted to be sent. /// and `authority`, or `headers` which are not permitted to be sent.
/// It is the obligation of the `outgoing-handler.handle` implementation /// It is the obligation of the `outgoing-handler.handle` implementation
/// to reject invalid constructions of `outgoing-request`. /// to reject invalid constructions of `outgoing-request`.
@since(version = 0.2.0)
constructor( constructor(
headers: headers headers: headers
); );
@@ -270,38 +331,47 @@ interface types {
/// Returns success on the first call: the `outgoing-body` resource for /// Returns success on the first call: the `outgoing-body` resource for
/// this `outgoing-request` can be retrieved at most once. Subsequent /// this `outgoing-request` can be retrieved at most once. Subsequent
/// calls will return error. /// calls will return error.
@since(version = 0.2.0)
body: func() -> result<outgoing-body>; body: func() -> result<outgoing-body>;
/// Get the Method for the Request. /// Get the Method for the Request.
@since(version = 0.2.0)
method: func() -> method; method: func() -> method;
/// Set the Method for the Request. Fails if the string present in a /// Set the Method for the Request. Fails if the string present in a
/// `method.other` argument is not a syntactically valid method. /// `method.other` argument is not a syntactically valid method.
@since(version = 0.2.0)
set-method: func(method: method) -> result; set-method: func(method: method) -> result;
/// Get the combination of the HTTP Path and Query for the Request. /// Get the combination of the HTTP Path and Query for the Request.
/// When `none`, this represents an empty Path and empty Query. /// When `none`, this represents an empty Path and empty Query.
@since(version = 0.2.0)
path-with-query: func() -> option<string>; path-with-query: func() -> option<string>;
/// Set the combination of the HTTP Path and Query for the Request. /// Set the combination of the HTTP Path and Query for the Request.
/// When `none`, this represents an empty Path and empty Query. Fails is the /// When `none`, this represents an empty Path and empty Query. Fails is the
/// string given is not a syntactically valid path and query uri component. /// string given is not a syntactically valid path and query uri component.
@since(version = 0.2.0)
set-path-with-query: func(path-with-query: option<string>) -> result; set-path-with-query: func(path-with-query: option<string>) -> result;
/// Get the HTTP Related Scheme for the Request. When `none`, the /// Get the HTTP Related Scheme for the Request. When `none`, the
/// implementation may choose an appropriate default scheme. /// implementation may choose an appropriate default scheme.
@since(version = 0.2.0)
scheme: func() -> option<scheme>; scheme: func() -> option<scheme>;
/// Set the HTTP Related Scheme for the Request. When `none`, the /// Set the HTTP Related Scheme for the Request. When `none`, the
/// implementation may choose an appropriate default scheme. Fails if the /// implementation may choose an appropriate default scheme. Fails if the
/// string given is not a syntactically valid uri scheme. /// string given is not a syntactically valid uri scheme.
@since(version = 0.2.0)
set-scheme: func(scheme: option<scheme>) -> result; set-scheme: func(scheme: option<scheme>) -> result;
/// Get the HTTP Authority for the Request. A value of `none` may be used /// Get the authority of the Request's target URI. A value of `none` may be used
/// with Related Schemes which do not require an Authority. The HTTP and /// with Related Schemes which do not require an authority. The HTTP and
/// HTTPS schemes always require an authority. /// HTTPS schemes always require an authority.
@since(version = 0.2.0)
authority: func() -> option<string>; authority: func() -> option<string>;
/// Set the HTTP Authority for the Request. A value of `none` may be used /// Set the authority of the Request's target URI. A value of `none` may be used
/// with Related Schemes which do not require an Authority. The HTTP and /// with Related Schemes which do not require an authority. The HTTP and
/// HTTPS schemes always require an authority. Fails if the string given is /// HTTPS schemes always require an authority. Fails if the string given is
/// not a syntactically valid uri authority. /// not a syntactically valid URI authority.
@since(version = 0.2.0)
set-authority: func(authority: option<string>) -> result; set-authority: func(authority: option<string>) -> result;
/// Get the headers associated with the Request. /// Get the headers associated with the Request.
@@ -310,8 +380,9 @@ interface types {
/// `delete` operations will fail with `header-error.immutable`. /// `delete` operations will fail with `header-error.immutable`.
/// ///
/// This headers resource is a child: it must be dropped before the parent /// This headers resource is a child: it must be dropped before the parent
/// `outgoing-request` is dropped, or its ownership is transfered to /// `outgoing-request` is dropped, or its ownership is transferred to
/// another component by e.g. `outgoing-handler.handle`. /// another component by e.g. `outgoing-handler.handle`.
@since(version = 0.2.0)
headers: func() -> headers; headers: func() -> headers;
} }
@@ -321,31 +392,39 @@ interface types {
/// ///
/// These timeouts are separate from any the user may use to bound a /// These timeouts are separate from any the user may use to bound a
/// blocking call to `wasi:io/poll.poll`. /// blocking call to `wasi:io/poll.poll`.
@since(version = 0.2.0)
resource request-options { resource request-options {
/// Construct a default `request-options` value. /// Construct a default `request-options` value.
@since(version = 0.2.0)
constructor(); constructor();
/// The timeout for the initial connect to the HTTP Server. /// The timeout for the initial connect to the HTTP Server.
@since(version = 0.2.0)
connect-timeout: func() -> option<duration>; connect-timeout: func() -> option<duration>;
/// Set the timeout for the initial connect to the HTTP Server. An error /// Set the timeout for the initial connect to the HTTP Server. An error
/// return value indicates that this timeout is not supported. /// return value indicates that this timeout is not supported.
@since(version = 0.2.0)
set-connect-timeout: func(duration: option<duration>) -> result; set-connect-timeout: func(duration: option<duration>) -> result;
/// The timeout for receiving the first byte of the Response body. /// The timeout for receiving the first byte of the Response body.
@since(version = 0.2.0)
first-byte-timeout: func() -> option<duration>; first-byte-timeout: func() -> option<duration>;
/// Set the timeout for receiving the first byte of the Response body. An /// Set the timeout for receiving the first byte of the Response body. An
/// error return value indicates that this timeout is not supported. /// error return value indicates that this timeout is not supported.
@since(version = 0.2.0)
set-first-byte-timeout: func(duration: option<duration>) -> result; set-first-byte-timeout: func(duration: option<duration>) -> result;
/// The timeout for receiving subsequent chunks of bytes in the Response /// The timeout for receiving subsequent chunks of bytes in the Response
/// body stream. /// body stream.
@since(version = 0.2.0)
between-bytes-timeout: func() -> option<duration>; between-bytes-timeout: func() -> option<duration>;
/// Set the timeout for receiving subsequent chunks of bytes in the Response /// Set the timeout for receiving subsequent chunks of bytes in the Response
/// body stream. An error return value indicates that this timeout is not /// body stream. An error return value indicates that this timeout is not
/// supported. /// supported.
@since(version = 0.2.0)
set-between-bytes-timeout: func(duration: option<duration>) -> result; set-between-bytes-timeout: func(duration: option<duration>) -> result;
} }
@@ -354,7 +433,23 @@ interface types {
/// This resource is used by the `wasi:http/incoming-handler` interface to /// This resource is used by the `wasi:http/incoming-handler` interface to
/// allow a Response to be sent corresponding to the Request provided as the /// allow a Response to be sent corresponding to the Request provided as the
/// other argument to `incoming-handler.handle`. /// other argument to `incoming-handler.handle`.
@since(version = 0.2.0)
resource response-outparam { resource response-outparam {
/// Send an HTTP 1xx response.
///
/// Unlike `response-outparam.set`, this does not consume the
/// `response-outparam`, allowing the guest to send an arbitrary number of
/// informational responses before sending the final response using
/// `response-outparam.set`.
///
/// This will return an `HTTP-protocol-error` if `status` is not in the
/// range [100-199], or an `internal-error` if the implementation does not
/// support informational responses.
@unstable(feature = informational-outbound-responses)
send-informational: func(
status: u16,
headers: headers
) -> result<_, error-code>;
/// Set the value of the `response-outparam` to either send a response, /// Set the value of the `response-outparam` to either send a response,
/// or indicate an error. /// or indicate an error.
@@ -365,6 +460,7 @@ interface types {
/// ///
/// The user may provide an `error` to `response` to allow the /// The user may provide an `error` to `response` to allow the
/// implementation determine how to respond with an HTTP error response. /// implementation determine how to respond with an HTTP error response.
@since(version = 0.2.0)
set: static func( set: static func(
param: response-outparam, param: response-outparam,
response: result<outgoing-response, error-code>, response: result<outgoing-response, error-code>,
@@ -372,12 +468,15 @@ interface types {
} }
/// This type corresponds to the HTTP standard Status Code. /// This type corresponds to the HTTP standard Status Code.
@since(version = 0.2.0)
type status-code = u16; type status-code = u16;
/// Represents an incoming HTTP Response. /// Represents an incoming HTTP Response.
@since(version = 0.2.0)
resource incoming-response { resource incoming-response {
/// Returns the status code from the incoming response. /// Returns the status code from the incoming response.
@since(version = 0.2.0)
status: func() -> status-code; status: func() -> status-code;
/// Returns the headers from the incoming response. /// Returns the headers from the incoming response.
@@ -387,10 +486,12 @@ interface types {
/// ///
/// This headers resource is a child: it must be dropped before the parent /// This headers resource is a child: it must be dropped before the parent
/// `incoming-response` is dropped. /// `incoming-response` is dropped.
@since(version = 0.2.0)
headers: func() -> headers; headers: func() -> headers;
/// Returns the incoming body. May be called at most once. Returns error /// Returns the incoming body. May be called at most once. Returns error
/// if called additional times. /// if called additional times.
@since(version = 0.2.0)
consume: func() -> result<incoming-body>; consume: func() -> result<incoming-body>;
} }
@@ -402,6 +503,7 @@ interface types {
/// an `input-stream` and the delivery of trailers as a `future-trailers`, /// an `input-stream` and the delivery of trailers as a `future-trailers`,
/// and ensures that the user of this interface may only be consuming either /// and ensures that the user of this interface may only be consuming either
/// the body contents or waiting on trailers at any given time. /// the body contents or waiting on trailers at any given time.
@since(version = 0.2.0)
resource incoming-body { resource incoming-body {
/// Returns the contents of the body, as a stream of bytes. /// Returns the contents of the body, as a stream of bytes.
@@ -419,26 +521,30 @@ interface types {
/// backpressure is to be applied when the user is consuming the body, /// backpressure is to be applied when the user is consuming the body,
/// and for that backpressure to not inhibit delivery of the trailers if /// and for that backpressure to not inhibit delivery of the trailers if
/// the user does not read the entire body. /// the user does not read the entire body.
@since(version = 0.2.0)
%stream: func() -> result<input-stream>; %stream: func() -> result<input-stream>;
/// Takes ownership of `incoming-body`, and returns a `future-trailers`. /// Takes ownership of `incoming-body`, and returns a `future-trailers`.
/// This function will trap if the `input-stream` child is still alive. /// This function will trap if the `input-stream` child is still alive.
@since(version = 0.2.0)
finish: static func(this: incoming-body) -> future-trailers; finish: static func(this: incoming-body) -> future-trailers;
} }
/// Represents a future which may eventaully return trailers, or an error. /// Represents a future which may eventually return trailers, or an error.
/// ///
/// In the case that the incoming HTTP Request or Response did not have any /// In the case that the incoming HTTP Request or Response did not have any
/// trailers, this future will resolve to the empty set of trailers once the /// trailers, this future will resolve to the empty set of trailers once the
/// complete Request or Response body has been received. /// complete Request or Response body has been received.
@since(version = 0.2.0)
resource future-trailers { resource future-trailers {
/// Returns a pollable which becomes ready when either the trailers have /// Returns a pollable which becomes ready when either the trailers have
/// been received, or an error has occured. When this pollable is ready, /// been received, or an error has occurred. When this pollable is ready,
/// the `get` method will return `some`. /// the `get` method will return `some`.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
/// Returns the contents of the trailers, or an error which occured, /// Returns the contents of the trailers, or an error which occurred,
/// once the future is ready. /// once the future is ready.
/// ///
/// The outer `option` represents future readiness. Users can wait on this /// The outer `option` represents future readiness. Users can wait on this
@@ -450,17 +556,19 @@ interface types {
/// ///
/// The inner `result` represents that either the HTTP Request or Response /// The inner `result` represents that either the HTTP Request or Response
/// body, as well as any trailers, were received successfully, or that an /// body, as well as any trailers, were received successfully, or that an
/// error occured receiving them. The optional `trailers` indicates whether /// error occurred receiving them. The optional `trailers` indicates whether
/// or not trailers were present in the body. /// or not trailers were present in the body.
/// ///
/// When some `trailers` are returned by this method, the `trailers` /// When some `trailers` are returned by this method, the `trailers`
/// resource is immutable, and a child. Use of the `set`, `append`, or /// resource is immutable, and a child. Use of the `set`, `append`, or
/// `delete` methods will return an error, and the resource must be /// `delete` methods will return an error, and the resource must be
/// dropped before the parent `future-trailers` is dropped. /// dropped before the parent `future-trailers` is dropped.
@since(version = 0.2.0)
get: func() -> option<result<result<option<trailers>, error-code>>>; get: func() -> option<result<result<option<trailers>, error-code>>>;
} }
/// Represents an outgoing HTTP Response. /// Represents an outgoing HTTP Response.
@since(version = 0.2.0)
resource outgoing-response { resource outgoing-response {
/// Construct an `outgoing-response`, with a default `status-code` of `200`. /// Construct an `outgoing-response`, with a default `status-code` of `200`.
@@ -468,13 +576,16 @@ interface types {
/// `set-status-code` method. /// `set-status-code` method.
/// ///
/// * `headers` is the HTTP Headers for the Response. /// * `headers` is the HTTP Headers for the Response.
@since(version = 0.2.0)
constructor(headers: headers); constructor(headers: headers);
/// Get the HTTP Status Code for the Response. /// Get the HTTP Status Code for the Response.
@since(version = 0.2.0)
status-code: func() -> status-code; status-code: func() -> status-code;
/// Set the HTTP Status Code for the Response. Fails if the status-code /// Set the HTTP Status Code for the Response. Fails if the status-code
/// given is not a valid http status code. /// given is not a valid http status code.
@since(version = 0.2.0)
set-status-code: func(status-code: status-code) -> result; set-status-code: func(status-code: status-code) -> result;
/// Get the headers associated with the Request. /// Get the headers associated with the Request.
@@ -483,8 +594,9 @@ interface types {
/// `delete` operations will fail with `header-error.immutable`. /// `delete` operations will fail with `header-error.immutable`.
/// ///
/// This headers resource is a child: it must be dropped before the parent /// This headers resource is a child: it must be dropped before the parent
/// `outgoing-request` is dropped, or its ownership is transfered to /// `outgoing-request` is dropped, or its ownership is transferred to
/// another component by e.g. `outgoing-handler.handle`. /// another component by e.g. `outgoing-handler.handle`.
@since(version = 0.2.0)
headers: func() -> headers; headers: func() -> headers;
/// Returns the resource corresponding to the outgoing Body for this Response. /// Returns the resource corresponding to the outgoing Body for this Response.
@@ -492,6 +604,7 @@ interface types {
/// Returns success on the first call: the `outgoing-body` resource for /// Returns success on the first call: the `outgoing-body` resource for
/// this `outgoing-response` can be retrieved at most once. Subsequent /// this `outgoing-response` can be retrieved at most once. Subsequent
/// calls will return error. /// calls will return error.
@since(version = 0.2.0)
body: func() -> result<outgoing-body>; body: func() -> result<outgoing-body>;
} }
@@ -507,10 +620,11 @@ interface types {
/// ///
/// If the user code drops this resource, as opposed to calling the static /// If the user code drops this resource, as opposed to calling the static
/// method `finish`, the implementation should treat the body as incomplete, /// method `finish`, the implementation should treat the body as incomplete,
/// and that an error has occured. The implementation should propogate this /// and that an error has occurred. The implementation should propagate this
/// error to the HTTP protocol by whatever means it has available, /// error to the HTTP protocol by whatever means it has available,
/// including: corrupting the body on the wire, aborting the associated /// including: corrupting the body on the wire, aborting the associated
/// Request, or sending a late status code for the Response. /// Request, or sending a late status code for the Response.
@since(version = 0.2.0)
resource outgoing-body { resource outgoing-body {
/// Returns a stream for writing the body contents. /// Returns a stream for writing the body contents.
@@ -522,6 +636,7 @@ interface types {
/// Returns success on the first call: the `output-stream` resource for /// Returns success on the first call: the `output-stream` resource for
/// this `outgoing-body` may be retrieved at most once. Subsequent calls /// this `outgoing-body` may be retrieved at most once. Subsequent calls
/// will return error. /// will return error.
@since(version = 0.2.0)
write: func() -> result<output-stream>; write: func() -> result<output-stream>;
/// Finalize an outgoing body, optionally providing trailers. This must be /// Finalize an outgoing body, optionally providing trailers. This must be
@@ -533,21 +648,24 @@ interface types {
/// constructed with a Content-Length header, and the contents written /// constructed with a Content-Length header, and the contents written
/// to the body (via `write`) does not match the value given in the /// to the body (via `write`) does not match the value given in the
/// Content-Length. /// Content-Length.
@since(version = 0.2.0)
finish: static func( finish: static func(
this: outgoing-body, this: outgoing-body,
trailers: option<trailers> trailers: option<trailers>
) -> result<_, error-code>; ) -> result<_, error-code>;
} }
/// Represents a future which may eventaully return an incoming HTTP /// Represents a future which may eventually return an incoming HTTP
/// Response, or an error. /// Response, or an error.
/// ///
/// This resource is returned by the `wasi:http/outgoing-handler` interface to /// This resource is returned by the `wasi:http/outgoing-handler` interface to
/// provide the HTTP Response corresponding to the sent Request. /// provide the HTTP Response corresponding to the sent Request.
@since(version = 0.2.0)
resource future-incoming-response { resource future-incoming-response {
/// Returns a pollable which becomes ready when either the Response has /// Returns a pollable which becomes ready when either the Response has
/// been received, or an error has occured. When this pollable is ready, /// been received, or an error has occurred. When this pollable is ready,
/// the `get` method will return `some`. /// the `get` method will return `some`.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
/// Returns the incoming HTTP Response, or an error, once one is ready. /// Returns the incoming HTTP Response, or an error, once one is ready.
@@ -560,11 +678,11 @@ interface types {
/// is `some`, and error on subsequent calls. /// is `some`, and error on subsequent calls.
/// ///
/// The inner `result` represents that either the incoming HTTP Response /// The inner `result` represents that either the incoming HTTP Response
/// status and headers have recieved successfully, or that an error /// status and headers have received successfully, or that an error
/// occured. Errors may also occur while consuming the response body, /// occurred. Errors may also occur while consuming the response body,
/// but those will be reported by the `incoming-body` and its /// but those will be reported by the `incoming-body` and its
/// `output-stream` child. /// `output-stream` child.
@since(version = 0.2.0)
get: func() -> option<result<result<incoming-response, error-code>>>; get: func() -> option<result<result<incoming-response, error-code>>>;
} }
} }

View File

@@ -1,6 +1,6 @@
package wasi:io@0.2.0; package wasi:io@0.2.4;
@since(version = 0.2.0)
interface error { interface error {
/// A resource which represents some error information. /// A resource which represents some error information.
/// ///
@@ -11,16 +11,15 @@ interface error {
/// `wasi:io/streams/stream-error` type. /// `wasi:io/streams/stream-error` type.
/// ///
/// To provide more specific error information, other interfaces may /// To provide more specific error information, other interfaces may
/// provide functions to further "downcast" this error into more specific /// offer functions to "downcast" this error into more specific types. For example,
/// error information. For example, `error`s returned in streams derived /// errors returned from streams derived from filesystem types can be described using
/// from filesystem types to be described using the filesystem's own /// the filesystem's own error-code type. This is done using the function
/// error-code type, using the function /// `wasi:filesystem/types/filesystem-error-code`, which takes a `borrow<error>`
/// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter /// parameter and returns an `option<wasi:filesystem/types/error-code>`.
/// `borrow<error>` and returns
/// `option<wasi:filesystem/types/error-code>`.
/// ///
/// The set of functions which can "downcast" an `error` into a more /// The set of functions which can "downcast" an `error` into a more
/// concrete type is open. /// concrete type is open.
@since(version = 0.2.0)
resource error { resource error {
/// Returns a string that is suitable to assist humans in debugging /// Returns a string that is suitable to assist humans in debugging
/// this error. /// this error.
@@ -29,6 +28,7 @@ interface error {
/// It may change across platforms, hosts, or other implementation /// It may change across platforms, hosts, or other implementation
/// details. Parsing this string is a major platform-compatibility /// details. Parsing this string is a major platform-compatibility
/// hazard. /// hazard.
@since(version = 0.2.0)
to-debug-string: func() -> string; to-debug-string: func() -> string;
} }
} }

View File

@@ -1,22 +1,26 @@
package wasi:io@0.2.0; package wasi:io@0.2.4;
/// A poll API intended to let users wait for I/O events on multiple handles /// A poll API intended to let users wait for I/O events on multiple handles
/// at once. /// at once.
@since(version = 0.2.0)
interface poll { interface poll {
/// `pollable` represents a single I/O event which may be ready, or not. /// `pollable` represents a single I/O event which may be ready, or not.
@since(version = 0.2.0)
resource pollable { resource pollable {
/// Return the readiness of a pollable. This function never blocks. /// Return the readiness of a pollable. This function never blocks.
/// ///
/// Returns `true` when the pollable is ready, and `false` otherwise. /// Returns `true` when the pollable is ready, and `false` otherwise.
ready: func() -> bool; @since(version = 0.2.0)
ready: func() -> bool;
/// `block` returns immediately if the pollable is ready, and otherwise /// `block` returns immediately if the pollable is ready, and otherwise
/// blocks until ready. /// blocks until ready.
/// ///
/// This function is equivalent to calling `poll.poll` on a list /// This function is equivalent to calling `poll.poll` on a list
/// containing only this pollable. /// containing only this pollable.
block: func(); @since(version = 0.2.0)
block: func();
} }
/// Poll for completion on a set of pollables. /// Poll for completion on a set of pollables.
@@ -27,8 +31,9 @@ interface poll {
/// The result `list<u32>` contains one or more indices of handles in the /// The result `list<u32>` contains one or more indices of handles in the
/// argument list that is ready for I/O. /// argument list that is ready for I/O.
/// ///
/// If the list contains more elements than can be indexed with a `u32` /// This function traps if either:
/// value, this function traps. /// - the list is empty, or:
/// - the list contains more elements than can be indexed with a `u32` value.
/// ///
/// A timeout can be implemented by adding a pollable from the /// A timeout can be implemented by adding a pollable from the
/// wasi-clocks API to the list. /// wasi-clocks API to the list.
@@ -36,6 +41,7 @@ interface poll {
/// This function does not return a `result`; polling in itself does not /// This function does not return a `result`; polling in itself does not
/// do any I/O so it doesn't fail. If any of the I/O sources identified by /// do any I/O so it doesn't fail. If any of the I/O sources identified by
/// the pollables has an error, it is indicated by marking the source as /// the pollables has an error, it is indicated by marking the source as
/// being reaedy for I/O. /// being ready for I/O.
@since(version = 0.2.0)
poll: func(in: list<borrow<pollable>>) -> list<u32>; poll: func(in: list<borrow<pollable>>) -> list<u32>;
} }

View File

@@ -1,19 +1,26 @@
package wasi:io@0.2.0; package wasi:io@0.2.4;
/// WASI I/O is an I/O abstraction API which is currently focused on providing /// WASI I/O is an I/O abstraction API which is currently focused on providing
/// stream types. /// stream types.
/// ///
/// In the future, the component model is expected to add built-in stream types; /// In the future, the component model is expected to add built-in stream types;
/// when it does, they are expected to subsume this API. /// when it does, they are expected to subsume this API.
@since(version = 0.2.0)
interface streams { interface streams {
@since(version = 0.2.0)
use error.{error}; use error.{error};
@since(version = 0.2.0)
use poll.{pollable}; use poll.{pollable};
/// An error for input-stream and output-stream operations. /// An error for input-stream and output-stream operations.
@since(version = 0.2.0)
variant stream-error { variant stream-error {
/// The last operation (a write or flush) failed before completion. /// The last operation (a write or flush) failed before completion.
/// ///
/// More information is available in the `error` payload. /// More information is available in the `error` payload.
///
/// After this, the stream will be closed. All future operations return
/// `stream-error::closed`.
last-operation-failed(error), last-operation-failed(error),
/// The stream is closed: no more input will be accepted by the /// The stream is closed: no more input will be accepted by the
/// stream. A closed output-stream will return this error on all /// stream. A closed output-stream will return this error on all
@@ -29,6 +36,7 @@ interface streams {
/// available, which could even be zero. To wait for data to be available, /// available, which could even be zero. To wait for data to be available,
/// use the `subscribe` function to obtain a `pollable` which can be polled /// use the `subscribe` function to obtain a `pollable` which can be polled
/// for using `wasi:io/poll`. /// for using `wasi:io/poll`.
@since(version = 0.2.0)
resource input-stream { resource input-stream {
/// Perform a non-blocking read from the stream. /// Perform a non-blocking read from the stream.
/// ///
@@ -56,6 +64,7 @@ interface streams {
/// is not possible to allocate in wasm32, or not desirable to allocate as /// is not possible to allocate in wasm32, or not desirable to allocate as
/// as a return value by the callee. The callee may return a list of bytes /// as a return value by the callee. The callee may return a list of bytes
/// less than `len` in size while more bytes are available for reading. /// less than `len` in size while more bytes are available for reading.
@since(version = 0.2.0)
read: func( read: func(
/// The maximum number of bytes to read /// The maximum number of bytes to read
len: u64 len: u64
@@ -63,6 +72,7 @@ interface streams {
/// Read bytes from a stream, after blocking until at least one byte can /// Read bytes from a stream, after blocking until at least one byte can
/// be read. Except for blocking, behavior is identical to `read`. /// be read. Except for blocking, behavior is identical to `read`.
@since(version = 0.2.0)
blocking-read: func( blocking-read: func(
/// The maximum number of bytes to read /// The maximum number of bytes to read
len: u64 len: u64
@@ -72,6 +82,7 @@ interface streams {
/// ///
/// Behaves identical to `read`, except instead of returning a list /// Behaves identical to `read`, except instead of returning a list
/// of bytes, returns the number of bytes consumed from the stream. /// of bytes, returns the number of bytes consumed from the stream.
@since(version = 0.2.0)
skip: func( skip: func(
/// The maximum number of bytes to skip. /// The maximum number of bytes to skip.
len: u64, len: u64,
@@ -79,6 +90,7 @@ interface streams {
/// Skip bytes from a stream, after blocking until at least one byte /// Skip bytes from a stream, after blocking until at least one byte
/// can be skipped. Except for blocking behavior, identical to `skip`. /// can be skipped. Except for blocking behavior, identical to `skip`.
@since(version = 0.2.0)
blocking-skip: func( blocking-skip: func(
/// The maximum number of bytes to skip. /// The maximum number of bytes to skip.
len: u64, len: u64,
@@ -90,6 +102,7 @@ interface streams {
/// The created `pollable` is a child resource of the `input-stream`. /// The created `pollable` is a child resource of the `input-stream`.
/// Implementations may trap if the `input-stream` is dropped before /// Implementations may trap if the `input-stream` is dropped before
/// all derived `pollable`s created with this function are dropped. /// all derived `pollable`s created with this function are dropped.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
} }
@@ -102,6 +115,11 @@ interface streams {
/// promptly, which could even be zero. To wait for the stream to be ready to /// promptly, which could even be zero. To wait for the stream to be ready to
/// accept data, the `subscribe` function to obtain a `pollable` which can be /// accept data, the `subscribe` function to obtain a `pollable` which can be
/// polled for using `wasi:io/poll`. /// polled for using `wasi:io/poll`.
///
/// Dropping an `output-stream` while there's still an active write in
/// progress may result in the data being lost. Before dropping the stream,
/// be sure to fully flush your writes.
@since(version = 0.2.0)
resource output-stream { resource output-stream {
/// Check readiness for writing. This function never blocks. /// Check readiness for writing. This function never blocks.
/// ///
@@ -112,6 +130,7 @@ interface streams {
/// When this function returns 0 bytes, the `subscribe` pollable will /// When this function returns 0 bytes, the `subscribe` pollable will
/// become ready when this function will report at least 1 byte, or an /// become ready when this function will report at least 1 byte, or an
/// error. /// error.
@since(version = 0.2.0)
check-write: func() -> result<u64, stream-error>; check-write: func() -> result<u64, stream-error>;
/// Perform a write. This function never blocks. /// Perform a write. This function never blocks.
@@ -127,6 +146,7 @@ interface streams {
/// ///
/// returns Err(closed) without writing if the stream has closed since /// returns Err(closed) without writing if the stream has closed since
/// the last call to check-write provided a permit. /// the last call to check-write provided a permit.
@since(version = 0.2.0)
write: func( write: func(
contents: list<u8> contents: list<u8>
) -> result<_, stream-error>; ) -> result<_, stream-error>;
@@ -155,6 +175,7 @@ interface streams {
/// // Check for any errors that arose during `flush` /// // Check for any errors that arose during `flush`
/// let _ = this.check-write(); // eliding error handling /// let _ = this.check-write(); // eliding error handling
/// ``` /// ```
@since(version = 0.2.0)
blocking-write-and-flush: func( blocking-write-and-flush: func(
contents: list<u8> contents: list<u8>
) -> result<_, stream-error>; ) -> result<_, stream-error>;
@@ -169,14 +190,16 @@ interface streams {
/// writes (`check-write` will return `ok(0)`) until the flush has /// writes (`check-write` will return `ok(0)`) until the flush has
/// completed. The `subscribe` pollable will become ready when the /// completed. The `subscribe` pollable will become ready when the
/// flush has completed and the stream can accept more writes. /// flush has completed and the stream can accept more writes.
@since(version = 0.2.0)
flush: func() -> result<_, stream-error>; flush: func() -> result<_, stream-error>;
/// Request to flush buffered output, and block until flush completes /// Request to flush buffered output, and block until flush completes
/// and stream is ready for writing again. /// and stream is ready for writing again.
@since(version = 0.2.0)
blocking-flush: func() -> result<_, stream-error>; blocking-flush: func() -> result<_, stream-error>;
/// Create a `pollable` which will resolve once the output-stream /// Create a `pollable` which will resolve once the output-stream
/// is ready for more writing, or an error has occured. When this /// is ready for more writing, or an error has occurred. When this
/// pollable is ready, `check-write` will return `ok(n)` with n>0, or an /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an
/// error. /// error.
/// ///
@@ -185,6 +208,7 @@ interface streams {
/// The created `pollable` is a child resource of the `output-stream`. /// The created `pollable` is a child resource of the `output-stream`.
/// Implementations may trap if the `output-stream` is dropped before /// Implementations may trap if the `output-stream` is dropped before
/// all derived `pollable`s created with this function are dropped. /// all derived `pollable`s created with this function are dropped.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
/// Write zeroes to a stream. /// Write zeroes to a stream.
@@ -193,6 +217,7 @@ interface streams {
/// preconditions (must use check-write first), but instead of /// preconditions (must use check-write first), but instead of
/// passing a list of bytes, you simply pass the number of zero-bytes /// passing a list of bytes, you simply pass the number of zero-bytes
/// that should be written. /// that should be written.
@since(version = 0.2.0)
write-zeroes: func( write-zeroes: func(
/// The number of zero-bytes to write /// The number of zero-bytes to write
len: u64 len: u64
@@ -222,6 +247,7 @@ interface streams {
/// // Check for any errors that arose during `flush` /// // Check for any errors that arose during `flush`
/// let _ = this.check-write(); // eliding error handling /// let _ = this.check-write(); // eliding error handling
/// ``` /// ```
@since(version = 0.2.0)
blocking-write-zeroes-and-flush: func( blocking-write-zeroes-and-flush: func(
/// The number of zero-bytes to write /// The number of zero-bytes to write
len: u64 len: u64
@@ -229,7 +255,7 @@ interface streams {
/// Read from one stream and write to another. /// Read from one stream and write to another.
/// ///
/// The behavior of splice is equivelant to: /// The behavior of splice is equivalent to:
/// 1. calling `check-write` on the `output-stream` /// 1. calling `check-write` on the `output-stream`
/// 2. calling `read` on the `input-stream` with the smaller of the /// 2. calling `read` on the `input-stream` with the smaller of the
/// `check-write` permitted length and the `len` provided to `splice` /// `check-write` permitted length and the `len` provided to `splice`
@@ -240,6 +266,7 @@ interface streams {
/// ///
/// This function returns the number of bytes transferred; it may be less /// This function returns the number of bytes transferred; it may be less
/// than `len`. /// than `len`.
@since(version = 0.2.0)
splice: func( splice: func(
/// The stream to read from /// The stream to read from
src: borrow<input-stream>, src: borrow<input-stream>,
@@ -252,6 +279,7 @@ interface streams {
/// This is similar to `splice`, except that it blocks until the /// This is similar to `splice`, except that it blocks until the
/// `output-stream` is ready for writing, and the `input-stream` /// `output-stream` is ready for writing, and the `input-stream`
/// is ready for reading, before performing the `splice`. /// is ready for reading, before performing the `splice`.
@since(version = 0.2.0)
blocking-splice: func( blocking-splice: func(
/// The stream to read from /// The stream to read from
src: borrow<input-stream>, src: borrow<input-stream>,

View File

@@ -1,6 +1,10 @@
package wasi:io@0.2.0; package wasi:io@0.2.4;
@since(version = 0.2.0)
world imports { world imports {
@since(version = 0.2.0)
import streams; import streams;
@since(version = 0.2.0)
import poll; import poll;
} }

View File

@@ -1,8 +1,9 @@
package wasi:random@0.2.0; package wasi:random@0.2.4;
/// The insecure-seed interface for seeding hash-map DoS resistance. /// The insecure-seed interface for seeding hash-map DoS resistance.
/// ///
/// It is intended to be portable at least between Unix-family platforms and /// It is intended to be portable at least between Unix-family platforms and
/// Windows. /// Windows.
@since(version = 0.2.0)
interface insecure-seed { interface insecure-seed {
/// Return a 128-bit value that may contain a pseudo-random value. /// Return a 128-bit value that may contain a pseudo-random value.
/// ///
@@ -21,5 +22,6 @@ interface insecure-seed {
/// This will likely be changed to a value import, to prevent it from being /// This will likely be changed to a value import, to prevent it from being
/// called multiple times and potentially used for purposes other than DoS /// called multiple times and potentially used for purposes other than DoS
/// protection. /// protection.
@since(version = 0.2.0)
insecure-seed: func() -> tuple<u64, u64>; insecure-seed: func() -> tuple<u64, u64>;
} }

View File

@@ -1,8 +1,9 @@
package wasi:random@0.2.0; package wasi:random@0.2.4;
/// The insecure interface for insecure pseudo-random numbers. /// The insecure interface for insecure pseudo-random numbers.
/// ///
/// It is intended to be portable at least between Unix-family platforms and /// It is intended to be portable at least between Unix-family platforms and
/// Windows. /// Windows.
@since(version = 0.2.0)
interface insecure { interface insecure {
/// Return `len` insecure pseudo-random bytes. /// Return `len` insecure pseudo-random bytes.
/// ///
@@ -12,11 +13,13 @@ interface insecure {
/// There are no requirements on the values of the returned bytes, however /// There are no requirements on the values of the returned bytes, however
/// implementations are encouraged to return evenly distributed values with /// implementations are encouraged to return evenly distributed values with
/// a long period. /// a long period.
@since(version = 0.2.0)
get-insecure-random-bytes: func(len: u64) -> list<u8>; get-insecure-random-bytes: func(len: u64) -> list<u8>;
/// Return an insecure pseudo-random `u64` value. /// Return an insecure pseudo-random `u64` value.
/// ///
/// This function returns the same type of pseudo-random data as /// This function returns the same type of pseudo-random data as
/// `get-insecure-random-bytes`, represented as a `u64`. /// `get-insecure-random-bytes`, represented as a `u64`.
@since(version = 0.2.0)
get-insecure-random-u64: func() -> u64; get-insecure-random-u64: func() -> u64;
} }

View File

@@ -1,8 +1,9 @@
package wasi:random@0.2.0; package wasi:random@0.2.4;
/// WASI Random is a random data API. /// WASI Random is a random data API.
/// ///
/// It is intended to be portable at least between Unix-family platforms and /// It is intended to be portable at least between Unix-family platforms and
/// Windows. /// Windows.
@since(version = 0.2.0)
interface random { interface random {
/// Return `len` cryptographically-secure random or pseudo-random bytes. /// Return `len` cryptographically-secure random or pseudo-random bytes.
/// ///
@@ -16,11 +17,13 @@ interface random {
/// This function must always return fresh data. Deterministic environments /// This function must always return fresh data. Deterministic environments
/// must omit this function, rather than implementing it with deterministic /// must omit this function, rather than implementing it with deterministic
/// data. /// data.
@since(version = 0.2.0)
get-random-bytes: func(len: u64) -> list<u8>; get-random-bytes: func(len: u64) -> list<u8>;
/// Return a cryptographically-secure random or pseudo-random `u64` value. /// Return a cryptographically-secure random or pseudo-random `u64` value.
/// ///
/// This function returns the same type of data as `get-random-bytes`, /// This function returns the same type of data as `get-random-bytes`,
/// represented as a `u64`. /// represented as a `u64`.
@since(version = 0.2.0)
get-random-u64: func() -> u64; get-random-u64: func() -> u64;
} }

View File

@@ -1,7 +1,13 @@
package wasi:random@0.2.0; package wasi:random@0.2.4;
@since(version = 0.2.0)
world imports { world imports {
@since(version = 0.2.0)
import random; import random;
@since(version = 0.2.0)
import insecure; import insecure;
@since(version = 0.2.0)
import insecure-seed; import insecure-seed;
} }

View File

@@ -1,9 +1,11 @@
/// This interface provides a value-export of the default network handle.. /// This interface provides a value-export of the default network handle..
@since(version = 0.2.0)
interface instance-network { interface instance-network {
@since(version = 0.2.0)
use network.{network}; use network.{network};
/// Get a handle to the default network. /// Get a handle to the default network.
@since(version = 0.2.0)
instance-network: func() -> network; instance-network: func() -> network;
} }

View File

@@ -1,9 +1,10 @@
@since(version = 0.2.0)
interface ip-name-lookup { interface ip-name-lookup {
use wasi:io/poll@0.2.0.{pollable}; @since(version = 0.2.0)
use wasi:io/poll@0.2.4.{pollable};
@since(version = 0.2.0)
use network.{network, error-code, ip-address}; use network.{network, error-code, ip-address};
/// Resolve an internet host name to a list of IP addresses. /// Resolve an internet host name to a list of IP addresses.
/// ///
/// Unicode domain names are automatically converted to ASCII using IDNA encoding. /// Unicode domain names are automatically converted to ASCII using IDNA encoding.
@@ -24,8 +25,10 @@ interface ip-name-lookup {
/// - <https://man7.org/linux/man-pages/man3/getaddrinfo.3.html> /// - <https://man7.org/linux/man-pages/man3/getaddrinfo.3.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo> /// - <https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo>
/// - <https://man.freebsd.org/cgi/man.cgi?query=getaddrinfo&sektion=3> /// - <https://man.freebsd.org/cgi/man.cgi?query=getaddrinfo&sektion=3>
@since(version = 0.2.0)
resolve-addresses: func(network: borrow<network>, name: string) -> result<resolve-address-stream, error-code>; resolve-addresses: func(network: borrow<network>, name: string) -> result<resolve-address-stream, error-code>;
@since(version = 0.2.0)
resource resolve-address-stream { resource resolve-address-stream {
/// Returns the next address from the resolver. /// Returns the next address from the resolver.
/// ///
@@ -40,12 +43,14 @@ interface ip-name-lookup {
/// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN)
/// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL)
/// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN)
@since(version = 0.2.0)
resolve-next-address: func() -> result<option<ip-address>, error-code>; resolve-next-address: func() -> result<option<ip-address>, error-code>;
/// Create a `pollable` which will resolve once the stream is ready for I/O. /// Create a `pollable` which will resolve once the stream is ready for I/O.
/// ///
/// Note: this function is here for WASI Preview2 only. /// Note: this function is here for WASI 0.2 only.
/// It's planned to be removed when `future` is natively supported in Preview3. /// It's planned to be removed when `future` is natively supported in Preview3.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
} }
} }

View File

@@ -1,8 +1,12 @@
@since(version = 0.2.0)
interface network { interface network {
@unstable(feature = network-error-code)
use wasi:io/error@0.2.4.{error};
/// An opaque resource that represents access to (a subset of) the network. /// An opaque resource that represents access to (a subset of) the network.
/// This enables context-based security for networking. /// This enables context-based security for networking.
/// There is no need for this to map 1:1 to a physical network interface. /// There is no need for this to map 1:1 to a physical network interface.
@since(version = 0.2.0)
resource network; resource network;
/// Error codes. /// Error codes.
@@ -17,6 +21,7 @@ interface network {
/// - `concurrency-conflict` /// - `concurrency-conflict`
/// ///
/// See each individual API for what the POSIX equivalents are. They sometimes differ per API. /// See each individual API for what the POSIX equivalents are. They sometimes differ per API.
@since(version = 0.2.0)
enum error-code { enum error-code {
/// Unknown error /// Unknown error
unknown, unknown,
@@ -103,6 +108,20 @@ interface network {
permanent-resolver-failure, permanent-resolver-failure,
} }
/// Attempts to extract a network-related `error-code` from the stream
/// `error` provided.
///
/// Stream operations which return `stream-error::last-operation-failed`
/// have a payload with more information about the operation that failed.
/// This payload can be passed through to this function to see if there's
/// network-related information about the error to return.
///
/// Note that this function is fallible because not all stream-related
/// errors are network-related errors.
@unstable(feature = network-error-code)
network-error-code: func(err: borrow<error>) -> option<error-code>;
@since(version = 0.2.0)
enum ip-address-family { enum ip-address-family {
/// Similar to `AF_INET` in POSIX. /// Similar to `AF_INET` in POSIX.
ipv4, ipv4,
@@ -111,14 +130,18 @@ interface network {
ipv6, ipv6,
} }
@since(version = 0.2.0)
type ipv4-address = tuple<u8, u8, u8, u8>; type ipv4-address = tuple<u8, u8, u8, u8>;
@since(version = 0.2.0)
type ipv6-address = tuple<u16, u16, u16, u16, u16, u16, u16, u16>; type ipv6-address = tuple<u16, u16, u16, u16, u16, u16, u16, u16>;
@since(version = 0.2.0)
variant ip-address { variant ip-address {
ipv4(ipv4-address), ipv4(ipv4-address),
ipv6(ipv6-address), ipv6(ipv6-address),
} }
@since(version = 0.2.0)
record ipv4-socket-address { record ipv4-socket-address {
/// sin_port /// sin_port
port: u16, port: u16,
@@ -126,6 +149,7 @@ interface network {
address: ipv4-address, address: ipv4-address,
} }
@since(version = 0.2.0)
record ipv6-socket-address { record ipv6-socket-address {
/// sin6_port /// sin6_port
port: u16, port: u16,
@@ -137,9 +161,9 @@ interface network {
scope-id: u32, scope-id: u32,
} }
@since(version = 0.2.0)
variant ip-socket-address { variant ip-socket-address {
ipv4(ipv4-socket-address), ipv4(ipv4-socket-address),
ipv6(ipv6-socket-address), ipv6(ipv6-socket-address),
} }
} }

View File

@@ -1,6 +1,8 @@
@since(version = 0.2.0)
interface tcp-create-socket { interface tcp-create-socket {
@since(version = 0.2.0)
use network.{network, error-code, ip-address-family}; use network.{network, error-code, ip-address-family};
@since(version = 0.2.0)
use tcp.{tcp-socket}; use tcp.{tcp-socket};
/// Create a new TCP socket. /// Create a new TCP socket.
@@ -23,5 +25,6 @@ interface tcp-create-socket {
/// - <https://man7.org/linux/man-pages/man2/socket.2.html> /// - <https://man7.org/linux/man-pages/man2/socket.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketw> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketw>
/// - <https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2> /// - <https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2>
@since(version = 0.2.0)
create-tcp-socket: func(address-family: ip-address-family) -> result<tcp-socket, error-code>; create-tcp-socket: func(address-family: ip-address-family) -> result<tcp-socket, error-code>;
} }

View File

@@ -1,10 +1,15 @@
@since(version = 0.2.0)
interface tcp { interface tcp {
use wasi:io/streams@0.2.0.{input-stream, output-stream}; @since(version = 0.2.0)
use wasi:io/poll@0.2.0.{pollable}; use wasi:io/streams@0.2.4.{input-stream, output-stream};
use wasi:clocks/monotonic-clock@0.2.0.{duration}; @since(version = 0.2.0)
use wasi:io/poll@0.2.4.{pollable};
@since(version = 0.2.0)
use wasi:clocks/monotonic-clock@0.2.4.{duration};
@since(version = 0.2.0)
use network.{network, error-code, ip-socket-address, ip-address-family}; use network.{network, error-code, ip-socket-address, ip-address-family};
@since(version = 0.2.0)
enum shutdown-type { enum shutdown-type {
/// Similar to `SHUT_RD` in POSIX. /// Similar to `SHUT_RD` in POSIX.
receive, receive,
@@ -27,8 +32,8 @@ interface tcp {
/// - `connect-in-progress` /// - `connect-in-progress`
/// - `connected` /// - `connected`
/// - `closed` /// - `closed`
/// See <https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md> /// See <https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md>
/// for a more information. /// for more information.
/// ///
/// Note: Except where explicitly mentioned, whenever this documentation uses /// Note: Except where explicitly mentioned, whenever this documentation uses
/// the term "bound" without backticks it actually means: in the `bound` state *or higher*. /// the term "bound" without backticks it actually means: in the `bound` state *or higher*.
@@ -37,6 +42,7 @@ interface tcp {
/// In addition to the general error codes documented on the /// In addition to the general error codes documented on the
/// `network::error-code` type, TCP socket methods may always return /// `network::error-code` type, TCP socket methods may always return
/// `error(invalid-state)` when in the `closed` state. /// `error(invalid-state)` when in the `closed` state.
@since(version = 0.2.0)
resource tcp-socket { resource tcp-socket {
/// Bind the socket to a specific network on the provided IP address and port. /// Bind the socket to a specific network on the provided IP address and port.
/// ///
@@ -76,13 +82,15 @@ interface tcp {
/// - <https://man7.org/linux/man-pages/man2/bind.2.html> /// - <https://man7.org/linux/man-pages/man2/bind.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind>
/// - <https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2&format=html> /// - <https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2&format=html>
@since(version = 0.2.0)
start-bind: func(network: borrow<network>, local-address: ip-socket-address) -> result<_, error-code>; start-bind: func(network: borrow<network>, local-address: ip-socket-address) -> result<_, error-code>;
@since(version = 0.2.0)
finish-bind: func() -> result<_, error-code>; finish-bind: func() -> result<_, error-code>;
/// Connect to a remote endpoint. /// Connect to a remote endpoint.
/// ///
/// On success: /// On success:
/// - the socket is transitioned into the `connection` state. /// - the socket is transitioned into the `connected` state.
/// - a pair of streams is returned that can be used to read & write to the connection /// - a pair of streams is returned that can be used to read & write to the connection
/// ///
/// After a failed connection attempt, the socket will be in the `closed` /// After a failed connection attempt, the socket will be in the `closed`
@@ -121,7 +129,9 @@ interface tcp {
/// - <https://man7.org/linux/man-pages/man2/connect.2.html> /// - <https://man7.org/linux/man-pages/man2/connect.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect>
/// - <https://man.freebsd.org/cgi/man.cgi?connect> /// - <https://man.freebsd.org/cgi/man.cgi?connect>
@since(version = 0.2.0)
start-connect: func(network: borrow<network>, remote-address: ip-socket-address) -> result<_, error-code>; start-connect: func(network: borrow<network>, remote-address: ip-socket-address) -> result<_, error-code>;
@since(version = 0.2.0)
finish-connect: func() -> result<tuple<input-stream, output-stream>, error-code>; finish-connect: func() -> result<tuple<input-stream, output-stream>, error-code>;
/// Start listening for new connections. /// Start listening for new connections.
@@ -149,7 +159,9 @@ interface tcp {
/// - <https://man7.org/linux/man-pages/man2/listen.2.html> /// - <https://man7.org/linux/man-pages/man2/listen.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen>
/// - <https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2> /// - <https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2>
@since(version = 0.2.0)
start-listen: func() -> result<_, error-code>; start-listen: func() -> result<_, error-code>;
@since(version = 0.2.0)
finish-listen: func() -> result<_, error-code>; finish-listen: func() -> result<_, error-code>;
/// Accept a new client socket. /// Accept a new client socket.
@@ -178,6 +190,7 @@ interface tcp {
/// - <https://man7.org/linux/man-pages/man2/accept.2.html> /// - <https://man7.org/linux/man-pages/man2/accept.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept>
/// - <https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2> /// - <https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2>
@since(version = 0.2.0)
accept: func() -> result<tuple<tcp-socket, input-stream, output-stream>, error-code>; accept: func() -> result<tuple<tcp-socket, input-stream, output-stream>, error-code>;
/// Get the bound local address. /// Get the bound local address.
@@ -196,6 +209,7 @@ interface tcp {
/// - <https://man7.org/linux/man-pages/man2/getsockname.2.html> /// - <https://man7.org/linux/man-pages/man2/getsockname.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getsockname> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getsockname>
/// - <https://man.freebsd.org/cgi/man.cgi?getsockname> /// - <https://man.freebsd.org/cgi/man.cgi?getsockname>
@since(version = 0.2.0)
local-address: func() -> result<ip-socket-address, error-code>; local-address: func() -> result<ip-socket-address, error-code>;
/// Get the remote address. /// Get the remote address.
@@ -208,16 +222,19 @@ interface tcp {
/// - <https://man7.org/linux/man-pages/man2/getpeername.2.html> /// - <https://man7.org/linux/man-pages/man2/getpeername.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getpeername> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getpeername>
/// - <https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1> /// - <https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1>
@since(version = 0.2.0)
remote-address: func() -> result<ip-socket-address, error-code>; remote-address: func() -> result<ip-socket-address, error-code>;
/// Whether the socket is in the `listening` state. /// Whether the socket is in the `listening` state.
/// ///
/// Equivalent to the SO_ACCEPTCONN socket option. /// Equivalent to the SO_ACCEPTCONN socket option.
@since(version = 0.2.0)
is-listening: func() -> bool; is-listening: func() -> bool;
/// Whether this is a IPv4 or IPv6 socket. /// Whether this is a IPv4 or IPv6 socket.
/// ///
/// Equivalent to the SO_DOMAIN socket option. /// Equivalent to the SO_DOMAIN socket option.
@since(version = 0.2.0)
address-family: func() -> ip-address-family; address-family: func() -> ip-address-family;
/// Hints the desired listen queue size. Implementations are free to ignore this. /// Hints the desired listen queue size. Implementations are free to ignore this.
@@ -229,6 +246,7 @@ interface tcp {
/// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen.
/// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-argument`: (set) The provided value was 0.
/// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state.
@since(version = 0.2.0)
set-listen-backlog-size: func(value: u64) -> result<_, error-code>; set-listen-backlog-size: func(value: u64) -> result<_, error-code>;
/// Enables or disables keepalive. /// Enables or disables keepalive.
@@ -240,7 +258,9 @@ interface tcp {
/// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true.
/// ///
/// Equivalent to the SO_KEEPALIVE socket option. /// Equivalent to the SO_KEEPALIVE socket option.
@since(version = 0.2.0)
keep-alive-enabled: func() -> result<bool, error-code>; keep-alive-enabled: func() -> result<bool, error-code>;
@since(version = 0.2.0)
set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; set-keep-alive-enabled: func(value: bool) -> result<_, error-code>;
/// Amount of time the connection has to be idle before TCP starts sending keepalive packets. /// Amount of time the connection has to be idle before TCP starts sending keepalive packets.
@@ -253,7 +273,9 @@ interface tcp {
/// ///
/// # Typical errors /// # Typical errors
/// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-argument`: (set) The provided value was 0.
@since(version = 0.2.0)
keep-alive-idle-time: func() -> result<duration, error-code>; keep-alive-idle-time: func() -> result<duration, error-code>;
@since(version = 0.2.0)
set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>;
/// The time between keepalive packets. /// The time between keepalive packets.
@@ -266,7 +288,9 @@ interface tcp {
/// ///
/// # Typical errors /// # Typical errors
/// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-argument`: (set) The provided value was 0.
@since(version = 0.2.0)
keep-alive-interval: func() -> result<duration, error-code>; keep-alive-interval: func() -> result<duration, error-code>;
@since(version = 0.2.0)
set-keep-alive-interval: func(value: duration) -> result<_, error-code>; set-keep-alive-interval: func(value: duration) -> result<_, error-code>;
/// The maximum amount of keepalive packets TCP should send before aborting the connection. /// The maximum amount of keepalive packets TCP should send before aborting the connection.
@@ -279,7 +303,9 @@ interface tcp {
/// ///
/// # Typical errors /// # Typical errors
/// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-argument`: (set) The provided value was 0.
@since(version = 0.2.0)
keep-alive-count: func() -> result<u32, error-code>; keep-alive-count: func() -> result<u32, error-code>;
@since(version = 0.2.0)
set-keep-alive-count: func(value: u32) -> result<_, error-code>; set-keep-alive-count: func(value: u32) -> result<_, error-code>;
/// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.
@@ -288,7 +314,9 @@ interface tcp {
/// ///
/// # Typical errors /// # Typical errors
/// - `invalid-argument`: (set) The TTL value must be 1 or higher. /// - `invalid-argument`: (set) The TTL value must be 1 or higher.
@since(version = 0.2.0)
hop-limit: func() -> result<u8, error-code>; hop-limit: func() -> result<u8, error-code>;
@since(version = 0.2.0)
set-hop-limit: func(value: u8) -> result<_, error-code>; set-hop-limit: func(value: u8) -> result<_, error-code>;
/// The kernel buffer space reserved for sends/receives on this socket. /// The kernel buffer space reserved for sends/receives on this socket.
@@ -301,9 +329,13 @@ interface tcp {
/// ///
/// # Typical errors /// # Typical errors
/// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-argument`: (set) The provided value was 0.
@since(version = 0.2.0)
receive-buffer-size: func() -> result<u64, error-code>; receive-buffer-size: func() -> result<u64, error-code>;
@since(version = 0.2.0)
set-receive-buffer-size: func(value: u64) -> result<_, error-code>; set-receive-buffer-size: func(value: u64) -> result<_, error-code>;
@since(version = 0.2.0)
send-buffer-size: func() -> result<u64, error-code>; send-buffer-size: func() -> result<u64, error-code>;
@since(version = 0.2.0)
set-send-buffer-size: func(value: u64) -> result<_, error-code>; set-send-buffer-size: func(value: u64) -> result<_, error-code>;
/// Create a `pollable` which can be used to poll for, or block on, /// Create a `pollable` which can be used to poll for, or block on,
@@ -318,11 +350,12 @@ interface tcp {
/// `subscribe` only has to be called once per socket and can then be /// `subscribe` only has to be called once per socket and can then be
/// (re)used for the remainder of the socket's lifetime. /// (re)used for the remainder of the socket's lifetime.
/// ///
/// See <https://github.com/WebAssembly/wasi-sockets/TcpSocketOperationalSemantics.md#Pollable-readiness> /// See <https://github.com/WebAssembly/wasi-sockets/blob/main/TcpSocketOperationalSemantics.md#pollable-readiness>
/// for a more information. /// for more information.
/// ///
/// Note: this function is here for WASI Preview2 only. /// Note: this function is here for WASI 0.2 only.
/// It's planned to be removed when `future` is natively supported in Preview3. /// It's planned to be removed when `future` is natively supported in Preview3.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
/// Initiate a graceful shutdown. /// Initiate a graceful shutdown.
@@ -335,7 +368,7 @@ interface tcp {
/// associated with this socket will be closed and a FIN packet will be sent. /// associated with this socket will be closed and a FIN packet will be sent.
/// - `both`: Same effect as `receive` & `send` combined. /// - `both`: Same effect as `receive` & `send` combined.
/// ///
/// This function is idempotent. Shutting a down a direction more than once /// This function is idempotent; shutting down a direction more than once
/// has no effect and returns `ok`. /// has no effect and returns `ok`.
/// ///
/// The shutdown function does not close (drop) the socket. /// The shutdown function does not close (drop) the socket.
@@ -348,6 +381,7 @@ interface tcp {
/// - <https://man7.org/linux/man-pages/man2/shutdown.2.html> /// - <https://man7.org/linux/man-pages/man2/shutdown.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown>
/// - <https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2> /// - <https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2>
@since(version = 0.2.0)
shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>;
} }
} }

View File

@@ -1,6 +1,8 @@
@since(version = 0.2.0)
interface udp-create-socket { interface udp-create-socket {
@since(version = 0.2.0)
use network.{network, error-code, ip-address-family}; use network.{network, error-code, ip-address-family};
@since(version = 0.2.0)
use udp.{udp-socket}; use udp.{udp-socket};
/// Create a new UDP socket. /// Create a new UDP socket.
@@ -23,5 +25,6 @@ interface udp-create-socket {
/// - <https://man7.org/linux/man-pages/man2/socket.2.html> /// - <https://man7.org/linux/man-pages/man2/socket.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketw> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketw>
/// - <https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2> /// - <https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2>
@since(version = 0.2.0)
create-udp-socket: func(address-family: ip-address-family) -> result<udp-socket, error-code>; create-udp-socket: func(address-family: ip-address-family) -> result<udp-socket, error-code>;
} }

View File

@@ -1,9 +1,12 @@
@since(version = 0.2.0)
interface udp { interface udp {
use wasi:io/poll@0.2.0.{pollable}; @since(version = 0.2.0)
use wasi:io/poll@0.2.4.{pollable};
@since(version = 0.2.0)
use network.{network, error-code, ip-socket-address, ip-address-family}; use network.{network, error-code, ip-socket-address, ip-address-family};
/// A received datagram. /// A received datagram.
@since(version = 0.2.0)
record incoming-datagram { record incoming-datagram {
/// The payload. /// The payload.
/// ///
@@ -19,6 +22,7 @@ interface udp {
} }
/// A datagram to be sent out. /// A datagram to be sent out.
@since(version = 0.2.0)
record outgoing-datagram { record outgoing-datagram {
/// The payload. /// The payload.
data: list<u8>, data: list<u8>,
@@ -33,9 +37,8 @@ interface udp {
remote-address: option<ip-socket-address>, remote-address: option<ip-socket-address>,
} }
/// A UDP socket handle. /// A UDP socket handle.
@since(version = 0.2.0)
resource udp-socket { resource udp-socket {
/// Bind the socket to a specific network on the provided IP address and port. /// Bind the socket to a specific network on the provided IP address and port.
/// ///
@@ -63,7 +66,9 @@ interface udp {
/// - <https://man7.org/linux/man-pages/man2/bind.2.html> /// - <https://man7.org/linux/man-pages/man2/bind.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind>
/// - <https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2&format=html> /// - <https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2&format=html>
@since(version = 0.2.0)
start-bind: func(network: borrow<network>, local-address: ip-socket-address) -> result<_, error-code>; start-bind: func(network: borrow<network>, local-address: ip-socket-address) -> result<_, error-code>;
@since(version = 0.2.0)
finish-bind: func() -> result<_, error-code>; finish-bind: func() -> result<_, error-code>;
/// Set up inbound & outbound communication channels, optionally to a specific peer. /// Set up inbound & outbound communication channels, optionally to a specific peer.
@@ -106,6 +111,7 @@ interface udp {
/// - <https://man7.org/linux/man-pages/man2/connect.2.html> /// - <https://man7.org/linux/man-pages/man2/connect.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect>
/// - <https://man.freebsd.org/cgi/man.cgi?connect> /// - <https://man.freebsd.org/cgi/man.cgi?connect>
@since(version = 0.2.0)
%stream: func(remote-address: option<ip-socket-address>) -> result<tuple<incoming-datagram-stream, outgoing-datagram-stream>, error-code>; %stream: func(remote-address: option<ip-socket-address>) -> result<tuple<incoming-datagram-stream, outgoing-datagram-stream>, error-code>;
/// Get the current bound address. /// Get the current bound address.
@@ -124,6 +130,7 @@ interface udp {
/// - <https://man7.org/linux/man-pages/man2/getsockname.2.html> /// - <https://man7.org/linux/man-pages/man2/getsockname.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getsockname> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getsockname>
/// - <https://man.freebsd.org/cgi/man.cgi?getsockname> /// - <https://man.freebsd.org/cgi/man.cgi?getsockname>
@since(version = 0.2.0)
local-address: func() -> result<ip-socket-address, error-code>; local-address: func() -> result<ip-socket-address, error-code>;
/// Get the address the socket is currently streaming to. /// Get the address the socket is currently streaming to.
@@ -136,11 +143,13 @@ interface udp {
/// - <https://man7.org/linux/man-pages/man2/getpeername.2.html> /// - <https://man7.org/linux/man-pages/man2/getpeername.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getpeername> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-getpeername>
/// - <https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1> /// - <https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2&n=1>
@since(version = 0.2.0)
remote-address: func() -> result<ip-socket-address, error-code>; remote-address: func() -> result<ip-socket-address, error-code>;
/// Whether this is a IPv4 or IPv6 socket. /// Whether this is a IPv4 or IPv6 socket.
/// ///
/// Equivalent to the SO_DOMAIN socket option. /// Equivalent to the SO_DOMAIN socket option.
@since(version = 0.2.0)
address-family: func() -> ip-address-family; address-family: func() -> ip-address-family;
/// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.
@@ -149,7 +158,9 @@ interface udp {
/// ///
/// # Typical errors /// # Typical errors
/// - `invalid-argument`: (set) The TTL value must be 1 or higher. /// - `invalid-argument`: (set) The TTL value must be 1 or higher.
@since(version = 0.2.0)
unicast-hop-limit: func() -> result<u8, error-code>; unicast-hop-limit: func() -> result<u8, error-code>;
@since(version = 0.2.0)
set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; set-unicast-hop-limit: func(value: u8) -> result<_, error-code>;
/// The kernel buffer space reserved for sends/receives on this socket. /// The kernel buffer space reserved for sends/receives on this socket.
@@ -162,18 +173,24 @@ interface udp {
/// ///
/// # Typical errors /// # Typical errors
/// - `invalid-argument`: (set) The provided value was 0. /// - `invalid-argument`: (set) The provided value was 0.
@since(version = 0.2.0)
receive-buffer-size: func() -> result<u64, error-code>; receive-buffer-size: func() -> result<u64, error-code>;
@since(version = 0.2.0)
set-receive-buffer-size: func(value: u64) -> result<_, error-code>; set-receive-buffer-size: func(value: u64) -> result<_, error-code>;
@since(version = 0.2.0)
send-buffer-size: func() -> result<u64, error-code>; send-buffer-size: func() -> result<u64, error-code>;
@since(version = 0.2.0)
set-send-buffer-size: func(value: u64) -> result<_, error-code>; set-send-buffer-size: func(value: u64) -> result<_, error-code>;
/// Create a `pollable` which will resolve once the socket is ready for I/O. /// Create a `pollable` which will resolve once the socket is ready for I/O.
/// ///
/// Note: this function is here for WASI Preview2 only. /// Note: this function is here for WASI 0.2 only.
/// It's planned to be removed when `future` is natively supported in Preview3. /// It's planned to be removed when `future` is natively supported in Preview3.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
} }
@since(version = 0.2.0)
resource incoming-datagram-stream { resource incoming-datagram-stream {
/// Receive messages on the socket. /// Receive messages on the socket.
/// ///
@@ -198,15 +215,18 @@ interface udp {
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom>
/// - <https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms741687(v=vs.85)> /// - <https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms741687(v=vs.85)>
/// - <https://man.freebsd.org/cgi/man.cgi?query=recv&sektion=2> /// - <https://man.freebsd.org/cgi/man.cgi?query=recv&sektion=2>
@since(version = 0.2.0)
receive: func(max-results: u64) -> result<list<incoming-datagram>, error-code>; receive: func(max-results: u64) -> result<list<incoming-datagram>, error-code>;
/// Create a `pollable` which will resolve once the stream is ready to receive again. /// Create a `pollable` which will resolve once the stream is ready to receive again.
/// ///
/// Note: this function is here for WASI Preview2 only. /// Note: this function is here for WASI 0.2 only.
/// It's planned to be removed when `future` is natively supported in Preview3. /// It's planned to be removed when `future` is natively supported in Preview3.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
} }
@since(version = 0.2.0)
resource outgoing-datagram-stream { resource outgoing-datagram-stream {
/// Check readiness for sending. This function never blocks. /// Check readiness for sending. This function never blocks.
/// ///
@@ -255,12 +275,14 @@ interface udp {
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendmsg> /// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendmsg>
/// - <https://man.freebsd.org/cgi/man.cgi?query=send&sektion=2> /// - <https://man.freebsd.org/cgi/man.cgi?query=send&sektion=2>
@since(version = 0.2.0)
send: func(datagrams: list<outgoing-datagram>) -> result<u64, error-code>; send: func(datagrams: list<outgoing-datagram>) -> result<u64, error-code>;
/// Create a `pollable` which will resolve once the stream is ready to send again. /// Create a `pollable` which will resolve once the stream is ready to send again.
/// ///
/// Note: this function is here for WASI Preview2 only. /// Note: this function is here for WASI 0.2 only.
/// It's planned to be removed when `future` is natively supported in Preview3. /// It's planned to be removed when `future` is natively supported in Preview3.
@since(version = 0.2.0)
subscribe: func() -> pollable; subscribe: func() -> pollable;
} }
} }

View File

@@ -1,11 +1,19 @@
package wasi:sockets@0.2.0; package wasi:sockets@0.2.4;
@since(version = 0.2.0)
world imports { world imports {
@since(version = 0.2.0)
import instance-network; import instance-network;
@since(version = 0.2.0)
import network; import network;
@since(version = 0.2.0)
import udp; import udp;
@since(version = 0.2.0)
import udp-create-socket; import udp-create-socket;
@since(version = 0.2.0)
import tcp; import tcp;
@since(version = 0.2.0)
import tcp-create-socket; import tcp-create-socket;
@since(version = 0.2.0)
import ip-name-lookup; import ip-name-lookup;
} }

Some files were not shown because too many files have changed in this diff Show More