diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 6dbe37ca9fba8..f1208e090f040 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -7,7 +7,7 @@ mod tests; )] use crate::{ io::{Error, OsFunctions, RawOsError}, - sys::io::{decode_error_kind, errno, error_string, is_interrupted}, + sys::io::{decode_error_kind, errno, format_error, is_interrupted}, }; // Because std is linked in during testing, these incoherent implementations would @@ -74,11 +74,8 @@ impl Error { #[must_use] #[inline] pub fn from_raw_os_error(code: RawOsError) -> Error { - const FUNCTIONS: &'static OsFunctions = &OsFunctions { - format_os_error: |code, fmt| fmt.write_str(&error_string(code)), - decode_error_kind, - is_interrupted, - }; + const FUNCTIONS: &'static OsFunctions = + &OsFunctions { format_os_error: format_error, decode_error_kind, is_interrupted }; // SAFETY: `FUNCTIONS` is a constant and not created at runtime. unsafe { Error::from_raw_os_error_with_functions(code, FUNCTIONS) } diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs index a3a2f5830ae91..7f75d7b4c980c 100644 --- a/library/std/src/io/error/tests.rs +++ b/library/std/src/io/error/tests.rs @@ -1,5 +1,5 @@ use crate::io::{Error, ErrorKind, const_error}; -use crate::sys::io::{decode_error_kind, error_string}; +use crate::sys::io::{decode_error_kind, format_error}; use crate::{assert_matches, error, fmt}; #[test] @@ -10,7 +10,7 @@ fn test_size() { #[test] fn test_debug_error() { let code = 6; - let msg = error_string(code); + let msg = fmt::from_fn(|f| format_error(code, f)).to_string(); let kind = decode_error_kind(code); let err = Error::new(ErrorKind::InvalidInput, Error::from_raw_os_error(code)); let expected = format!( diff --git a/library/std/src/sys/io/error/generic.rs b/library/std/src/sys/io/error/generic.rs index fc70fbaba7e8c..1ff0e9303041d 100644 --- a/library/std/src/sys/io/error/generic.rs +++ b/library/std/src/sys/io/error/generic.rs @@ -1,3 +1,5 @@ +use crate::fmt; + pub fn errno() -> i32 { 0 } @@ -10,6 +12,6 @@ pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { crate::io::ErrorKind::Uncategorized } -pub fn error_string(_errno: i32) -> String { - "operation successful".to_string() +pub fn format_error(_errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("operation successful") } diff --git a/library/std/src/sys/io/error/hermit.rs b/library/std/src/sys/io/error/hermit.rs index 5f42144bb7cfb..28735c4c8275c 100644 --- a/library/std/src/sys/io/error/hermit.rs +++ b/library/std/src/sys/io/error/hermit.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::{fmt, io}; pub fn errno() -> i32 { unsafe { hermit_abi::get_errno() } @@ -30,6 +30,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { } } -pub fn error_string(errno: i32) -> String { - hermit_abi::error_string(errno).to_string() +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let description = hermit_abi::error_string(errno); + f.write_str(description) } diff --git a/library/std/src/sys/io/error/motor.rs b/library/std/src/sys/io/error/motor.rs index 06417417e8554..3afbd3fa9b7f1 100644 --- a/library/std/src/sys/io/error/motor.rs +++ b/library/std/src/sys/io/error/motor.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::{fmt, io}; pub fn errno() -> io::RawOsError { // Not used in Motor OS because it is ambiguous: Motor OS @@ -57,11 +57,12 @@ pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { } } -pub fn error_string(errno: io::RawOsError) -> String { - let error: moto_rt::Error = match errno { +pub fn format_error(errno: io::RawOsError, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let error = match errno { x if x < 0 => moto_rt::Error::Unknown, x if x > u16::MAX.into() => moto_rt::Error::Unknown, - x => (x as moto_rt::ErrorCode).into(), /* u16 */ + x => moto_rt::Error::from(x as moto_rt::ErrorCode), /* u16 */ }; - format!("{}", error) + + write!(f, "{error}") } diff --git a/library/std/src/sys/io/error/sgx.rs b/library/std/src/sys/io/error/sgx.rs index b7b4030422e12..2d0827aad39ab 100644 --- a/library/std/src/sys/io/error/sgx.rs +++ b/library/std/src/sys/io/error/sgx.rs @@ -1,6 +1,6 @@ use fortanix_sgx_abi::{Error, RESULT_SUCCESS}; -use crate::io; +use crate::{fmt, io}; pub fn errno() -> i32 { RESULT_SUCCESS @@ -54,12 +54,13 @@ pub fn decode_error_kind(code: i32) -> io::ErrorKind { } } -pub fn error_string(errno: i32) -> String { +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { if errno == RESULT_SUCCESS { - "operation successful".into() + f.write_str("operation successful") } else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) { - format!("user-specified error {errno:08x}") + write!(f, "user-specified error {errno:08x}") } else { - format!("{}", decode_error_kind(errno)) + let kind = decode_error_kind(errno); + write!(f, "{kind}") } } diff --git a/library/std/src/sys/io/error/solid.rs b/library/std/src/sys/io/error/solid.rs index 8e9503272abbc..ced354cb4c6e2 100644 --- a/library/std/src/sys/io/error/solid.rs +++ b/library/std/src/sys/io/error/solid.rs @@ -1,5 +1,5 @@ -use crate::io; use crate::sys::pal::error; +use crate::{fmt, io}; pub fn errno() -> i32 { 0 @@ -14,6 +14,6 @@ pub fn decode_error_kind(code: i32) -> io::ErrorKind { error::decode_error_kind(code) } -pub fn error_string(errno: i32) -> String { - if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") } +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(name) = error::error_name(errno) { f.write_str(name) } else { write!(f, "{errno}") } } diff --git a/library/std/src/sys/io/error/uefi.rs b/library/std/src/sys/io/error/uefi.rs index bedea240d523b..a8793f2799be9 100644 --- a/library/std/src/sys/io/error/uefi.rs +++ b/library/std/src/sys/io/error/uefi.rs @@ -1,6 +1,6 @@ use r_efi::efi::Status; -use crate::io; +use crate::{fmt, io}; pub fn errno() -> io::RawOsError { 0 @@ -54,7 +54,7 @@ pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { } } -pub fn error_string(errno: io::RawOsError) -> String { +pub fn format_error(errno: io::RawOsError, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Keep the List in Alphabetical Order // The Messages are taken from UEFI Specification Appendix D - Status Codes #[rustfmt::skip] @@ -98,7 +98,7 @@ pub fn error_string(errno: io::RawOsError) -> String { Status::VOLUME_FULL => "There is no more space on the file system.", Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.", Status::WRITE_PROTECTED => "The device cannot be written to.", - _ => return format!("Status: {errno}"), + _ => return write!(f, "Status: {errno}"), }; - msg.to_owned() + f.write_str(msg) } diff --git a/library/std/src/sys/io/error/unix.rs b/library/std/src/sys/io/error/unix.rs index 12acde7311e4c..5f60abf9d9528 100644 --- a/library/std/src/sys/io/error/unix.rs +++ b/library/std/src/sys/io/error/unix.rs @@ -1,7 +1,7 @@ use crate::ffi::c_int; #[cfg(not(target_os = "teeos"))] use crate::ffi::{CStr, c_char}; -use crate::io; +use crate::{fmt, io}; unsafe extern "C" { #[cfg(not(any( @@ -195,7 +195,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { /// Gets a detailed string description for the given error number. #[cfg(any(target_family = "unix", target_os = "wasi"))] -pub fn error_string(errno: i32) -> String { +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { const TMPBUF_SZ: usize = if cfg!(target_os = "wasi") { 1024 } else { 128 }; unsafe extern "C" { @@ -226,11 +226,11 @@ pub fn error_string(errno: i32) -> String { let p = p as *const _; // We can't always expect a UTF-8 environment. When we don't get that luxury, // it's better to give a low-quality error message than none at all. - String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into() + write!(f, "{}", CStr::from_ptr(p).display()) } } #[cfg(target_os = "teeos")] -pub fn error_string(_errno: i32) -> String { - "error string unimplemented".to_string() +pub fn format_error(_errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("error string unimplemented") } diff --git a/library/std/src/sys/io/error/windows.rs b/library/std/src/sys/io/error/windows.rs index 0ca3aee389b3e..6056f1774c146 100644 --- a/library/std/src/sys/io/error/windows.rs +++ b/library/std/src/sys/io/error/windows.rs @@ -1,5 +1,5 @@ use crate::sys::pal::{api, c}; -use crate::{io, ptr}; +use crate::{fmt, io, ptr}; #[cfg(test)] mod tests; @@ -95,7 +95,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { } /// Gets a detailed string description for the given error number. -pub fn error_string(mut errnum: i32) -> String { +pub fn format_error(mut errnum: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut buf = [0 as c::WCHAR; 2048]; unsafe { @@ -131,21 +131,15 @@ pub fn error_string(mut errnum: i32) -> String { if res == 0 { // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId, let fm_err = errno(); - return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})"); + return write!(f, "OS Error {errnum} (FormatMessageW() returned error {fm_err})"); } match String::from_utf16(&buf[..res]) { - Ok(mut msg) => { + Ok(msg) => { // Trim trailing CRLF inserted by FormatMessageW - let len = msg.trim_ascii_end().len(); - msg.truncate(len); - msg + f.write_str(msg.trim_ascii_end()) } - Err(..) => format!( - "OS Error {} (FormatMessageW() returned \ - invalid UTF-16)", - errnum - ), + Err(..) => write!(f, "OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum), } } } diff --git a/library/std/src/sys/io/error/windows/tests.rs b/library/std/src/sys/io/error/windows/tests.rs index 7fc545ad00666..088472eceab71 100644 --- a/library/std/src/sys/io/error/windows/tests.rs +++ b/library/std/src/sys/io/error/windows/tests.rs @@ -1,7 +1,7 @@ use crate::io::Error; use crate::sys::pal::c; -// tests `error_string` above +// tests `format_error` #[test] fn ntstatus_error() { const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001; diff --git a/library/std/src/sys/io/error/xous.rs b/library/std/src/sys/io/error/xous.rs index 2e9ea8e4f0928..bdecf437d0126 100644 --- a/library/std/src/sys/io/error/xous.rs +++ b/library/std/src/sys/io/error/xous.rs @@ -1,3 +1,4 @@ +use crate::fmt; use crate::os::xous::ffi::Error as XousError; pub fn errno() -> i32 { @@ -12,6 +13,7 @@ pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { crate::io::ErrorKind::Uncategorized } -pub fn error_string(errno: i32) -> String { - Into::::into(errno).to_string() +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let error = XousError::from(errno); + write!(f, "{error}") } diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index 33182e4eb5539..b9c48e3fe6ba5 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -51,5 +51,5 @@ pub use error::errno_location; target_os = "wasi", ))] pub use error::set_errno; -pub use error::{decode_error_kind, errno, error_string, is_interrupted}; +pub use error::{decode_error_kind, errno, format_error, is_interrupted}; pub use is_terminal::is_terminal; diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index 0f5c7c9a58c40..8c233a0d2024e 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -8,7 +8,7 @@ use crate::num::{NonZero, NonZeroI32}; use crate::path::{Path, PathBuf}; use crate::process::StdioPipes; use crate::sys::fs::File; -use crate::sys::io::error_string; +use crate::sys::io::format_error; use crate::sys::pal::helpers; use crate::sys::unsupported; use crate::{fmt, io}; @@ -264,8 +264,7 @@ impl ExitStatus { impl fmt::Display for ExitStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let err_str = error_string(self.0.as_usize()); - write!(f, "{}", err_str) + format_error(self.0.as_usize(), f) } } @@ -280,8 +279,7 @@ pub struct ExitStatusError(r_efi::efi::Status); impl fmt::Debug for ExitStatusError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let err_str = error_string(self.0.as_usize()); - write!(f, "{}", err_str) + format_error(self.0.as_usize(), f) } }