From 4588b54de61321789115e08dcb3ae5610528f7c4 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 19 Mar 2022 16:33:39 +0100 Subject: [PATCH 1/3] Update to wasi 0.11 The main breaking change between v0.10 and v0.11 is that Error is removed in favour of Errno. Unfortunately we can't create an Errno from outside the wasi create so we're loosing some debug information for errors. I've opened an issue to add back such a constructor, see . --- Cargo.toml | 2 +- src/error.rs | 6 ++++-- src/wasi.rs | 14 ++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6630982a..8d01d5851 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" libc = { version = "0.2.120", default-features = false } [target.'cfg(target_os = "wasi")'.dependencies] -wasi = "0.10" +wasi = "0.11" [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] wasm-bindgen = { version = "0.2.62", default-features = false, optional = true } diff --git a/src/error.rs b/src/error.rs index 661575376..469d7e55e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -110,8 +110,10 @@ cfg_if! { core::str::from_utf8(&buf[..idx]).ok() } } else if #[cfg(target_os = "wasi")] { - fn os_err(errno: i32, _buf: &mut [u8]) -> Option { - wasi::Error::from_raw_error(errno as _) + fn os_err(errno: i32, _buf: &mut [u8]) -> Option { + // Can't create `Errno` at the moment, see + // . + None } } else { fn os_err(_errno: i32, _buf: &mut [u8]) -> Option<&str> { diff --git a/src/wasi.rs b/src/wasi.rs index 2d413e020..4d13798cc 100644 --- a/src/wasi.rs +++ b/src/wasi.rs @@ -12,12 +12,10 @@ use core::num::NonZeroU32; use wasi::random_get; pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { - unsafe { - random_get(dest.as_mut_ptr(), dest.len()).map_err(|e: wasi::Error| { - // convert wasi's Error into getrandom's NonZeroU32 error - // SAFETY: `wasi::Error` is `NonZeroU16` internally, so `e.raw_error()` - // will never return 0 - NonZeroU32::new_unchecked(e.raw_error() as u32).into() - }) - } + random_get(dest.as_mut_ptr(), dest.len()).map_err(|e: wasi::Errno| { + // NOTE: `random_get` deals with return value of zero for us, so the + // unwrap below won't panic. However in case the code ever changes we + // don't want to use `new_unchecked` and cause UB. + NonZeroU32::new(e.raw() as u32).unwrap().into() + }) } From 3487d642d7564fbf263971ffb6b11d9b2fe53644 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 26 Mar 2022 14:09:57 +0100 Subject: [PATCH 2/3] Use libc::strerror to get the error message on wasi Since wasi v0.11 doesn't (yet) provided a way to create Errno, see . --- Cargo.toml | 2 +- src/error.rs | 8 +------- src/wasi.rs | 12 +++++------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8d01d5851..c0c1b12f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = "1" compiler_builtins = { version = "0.1", optional = true } core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" } -[target.'cfg(unix)'.dependencies] +[target.'cfg(any(unix, target_os = "wasi"))'.dependencies] libc = { version = "0.2.120", default-features = false } [target.'cfg(target_os = "wasi")'.dependencies] diff --git a/src/error.rs b/src/error.rs index 469d7e55e..c9b680287 100644 --- a/src/error.rs +++ b/src/error.rs @@ -97,7 +97,7 @@ impl Error { } cfg_if! { - if #[cfg(unix)] { + if #[cfg(any(unix, target_os = "wasi"))] { fn os_err(errno: i32, buf: &mut [u8]) -> Option<&str> { let buf_ptr = buf.as_mut_ptr() as *mut libc::c_char; if unsafe { libc::strerror_r(errno, buf_ptr, buf.len()) } != 0 { @@ -109,12 +109,6 @@ cfg_if! { let idx = buf.iter().position(|&b| b == 0).unwrap_or(n); core::str::from_utf8(&buf[..idx]).ok() } - } else if #[cfg(target_os = "wasi")] { - fn os_err(errno: i32, _buf: &mut [u8]) -> Option { - // Can't create `Errno` at the moment, see - // . - None - } } else { fn os_err(_errno: i32, _buf: &mut [u8]) -> Option<&str> { None diff --git a/src/wasi.rs b/src/wasi.rs index 4d13798cc..c5121824a 100644 --- a/src/wasi.rs +++ b/src/wasi.rs @@ -9,13 +9,11 @@ //! Implementation for WASI use crate::Error; use core::num::NonZeroU32; -use wasi::random_get; +use wasi::wasi_snapshot_preview1::random_get; pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { - random_get(dest.as_mut_ptr(), dest.len()).map_err(|e: wasi::Errno| { - // NOTE: `random_get` deals with return value of zero for us, so the - // unwrap below won't panic. However in case the code ever changes we - // don't want to use `new_unchecked` and cause UB. - NonZeroU32::new(e.raw() as u32).unwrap().into() - }) + match unsafe { random_get(dest.as_mut_ptr() as i32, dest.len() as i32) } { + 0 => Ok(()), + err => Err(unsafe { NonZeroU32::new_unchecked(err as u32) }.into()), + } } From 523b44325d35ed2e68c22bc8346bd4fff82fb025 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 29 Mar 2022 13:47:44 +0200 Subject: [PATCH 3/3] Remove libc dependency for WASI This does mean that we won't get an error message for the error type. --- Cargo.toml | 2 +- src/error.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c0c1b12f5..8d01d5851 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = "1" compiler_builtins = { version = "0.1", optional = true } core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" } -[target.'cfg(any(unix, target_os = "wasi"))'.dependencies] +[target.'cfg(unix)'.dependencies] libc = { version = "0.2.120", default-features = false } [target.'cfg(target_os = "wasi")'.dependencies] diff --git a/src/error.rs b/src/error.rs index c9b680287..b5ab2bb18 100644 --- a/src/error.rs +++ b/src/error.rs @@ -97,7 +97,7 @@ impl Error { } cfg_if! { - if #[cfg(any(unix, target_os = "wasi"))] { + if #[cfg(unix)] { fn os_err(errno: i32, buf: &mut [u8]) -> Option<&str> { let buf_ptr = buf.as_mut_ptr() as *mut libc::c_char; if unsafe { libc::strerror_r(errno, buf_ptr, buf.len()) } != 0 {