Skip to content

Commit 40e873d

Browse files
authored
Remove use of locale-specific strerror_r (#440)
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.
1 parent b2bca0f commit 40e873d

File tree

1 file changed

+11
-28
lines changed

1 file changed

+11
-28
lines changed

src/error.rs

+11-28
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#[cfg(feature = "std")]
2+
extern crate std;
3+
14
use core::{fmt, num::NonZeroU32};
25

36
/// A small and `no_std` compatible error type
@@ -98,35 +101,13 @@ impl Error {
98101
}
99102
}
100103

101-
cfg_if! {
102-
if #[cfg(unix)] {
103-
fn os_err(errno: i32, buf: &mut [u8]) -> Option<&str> {
104-
let buf_ptr = buf.as_mut_ptr().cast::<libc::c_char>();
105-
if unsafe { libc::strerror_r(errno, buf_ptr, buf.len()) } != 0 {
106-
return None;
107-
}
108-
109-
// Take up to trailing null byte
110-
let n = buf.len();
111-
let idx = buf.iter().position(|&b| b == 0).unwrap_or(n);
112-
core::str::from_utf8(&buf[..idx]).ok()
113-
}
114-
} else {
115-
fn os_err(_errno: i32, _buf: &mut [u8]) -> Option<&str> {
116-
None
117-
}
118-
}
119-
}
120-
121104
impl fmt::Debug for Error {
122105
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123106
let mut dbg = f.debug_struct("Error");
124107
if let Some(errno) = self.raw_os_error() {
125108
dbg.field("os_error", &errno);
126-
let mut buf = [0u8; 128];
127-
if let Some(err) = os_err(errno, &mut buf) {
128-
dbg.field("description", &err);
129-
}
109+
#[cfg(feature = "std")]
110+
dbg.field("description", &std::io::Error::from_raw_os_error(errno));
130111
} else if let Some(desc) = internal_desc(*self) {
131112
dbg.field("internal_code", &self.0.get());
132113
dbg.field("description", &desc);
@@ -140,10 +121,12 @@ impl fmt::Debug for Error {
140121
impl fmt::Display for Error {
141122
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142123
if let Some(errno) = self.raw_os_error() {
143-
let mut buf = [0u8; 128];
144-
match os_err(errno, &mut buf) {
145-
Some(err) => err.fmt(f),
146-
None => write!(f, "OS Error: {}", errno),
124+
cfg_if! {
125+
if #[cfg(feature = "std")] {
126+
std::io::Error::from_raw_os_error(errno).fmt(f)
127+
} else {
128+
write!(f, "OS Error: {}", errno)
129+
}
147130
}
148131
} else if let Some(desc) = internal_desc(*self) {
149132
f.write_str(desc)

0 commit comments

Comments
 (0)