From f8a69c5c68e15266ffbf497272ab26043ee8c012 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Wed, 29 May 2024 17:14:08 -0700 Subject: [PATCH 1/2] Remove use of locale-specific `strerror_r`. strerror_r doesn't necessarily return UTF-8 but we assume it does. strerror_r is locale-sensitive but we are better off not being locale-sensitive. strerror_r requires us to use libc but increasingly we want to avoid libc, e.g. to support x86_64-unknown-linux-none. Just remove the use of the function. --- src/error.rs | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/src/error.rs b/src/error.rs index 3ba4ff6c1..92dfe22da 100644 --- a/src/error.rs +++ b/src/error.rs @@ -98,35 +98,11 @@ impl Error { } } -cfg_if! { - if #[cfg(unix)] { - fn os_err(errno: i32, buf: &mut [u8]) -> Option<&str> { - let buf_ptr = buf.as_mut_ptr().cast::(); - if unsafe { libc::strerror_r(errno, buf_ptr, buf.len()) } != 0 { - return None; - } - - // Take up to trailing null byte - let n = buf.len(); - let idx = buf.iter().position(|&b| b == 0).unwrap_or(n); - core::str::from_utf8(&buf[..idx]).ok() - } - } else { - fn os_err(_errno: i32, _buf: &mut [u8]) -> Option<&str> { - None - } - } -} - impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut dbg = f.debug_struct("Error"); if let Some(errno) = self.raw_os_error() { dbg.field("os_error", &errno); - let mut buf = [0u8; 128]; - if let Some(err) = os_err(errno, &mut buf) { - dbg.field("description", &err); - } } else if let Some(desc) = internal_desc(*self) { dbg.field("internal_code", &self.0.get()); dbg.field("description", &desc); @@ -140,11 +116,7 @@ impl fmt::Debug for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(errno) = self.raw_os_error() { - let mut buf = [0u8; 128]; - match os_err(errno, &mut buf) { - Some(err) => err.fmt(f), - None => write!(f, "OS Error: {}", errno), - } + write!(f, "OS Error: {}", errno) } else if let Some(desc) = internal_desc(*self) { f.write_str(desc) } else { From 1cbce31c1107cd4efe45f4d2a8977e2d66d01a78 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Fri, 31 May 2024 15:16:36 -0700 Subject: [PATCH 2/2] Use `std::io::Error` for `Debug` and `Display` when it is available. --- src/error.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index 92dfe22da..20892ec59 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,6 @@ +#[cfg(feature = "std")] +extern crate std; + use core::{fmt, num::NonZeroU32}; /// A small and `no_std` compatible error type @@ -103,6 +106,8 @@ impl fmt::Debug for Error { let mut dbg = f.debug_struct("Error"); if let Some(errno) = self.raw_os_error() { dbg.field("os_error", &errno); + #[cfg(feature = "std")] + dbg.field("description", &std::io::Error::from_raw_os_error(errno)); } else if let Some(desc) = internal_desc(*self) { dbg.field("internal_code", &self.0.get()); dbg.field("description", &desc); @@ -116,7 +121,13 @@ impl fmt::Debug for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(errno) = self.raw_os_error() { - write!(f, "OS Error: {}", errno) + cfg_if! { + if #[cfg(feature = "std")] { + std::io::Error::from_raw_os_error(errno).fmt(f) + } else { + write!(f, "OS Error: {}", errno) + } + } } else if let Some(desc) = internal_desc(*self) { f.write_str(desc) } else {