1
Fork 0

Rollup merge of #139081 - joboet:errno_dedup, r=Noratrieb

std: deduplicate `errno` accesses

By marking `__errno_location` as `#[ffi_const]` and `std::sys::os::errno` as `#[inline]`, this PR allows merging multiple calls to `io::Error::last_os_error()` into one.
This commit is contained in:
Matthias Krüger 2025-03-29 21:08:12 +01:00 committed by GitHub
commit 821e0fe0a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 9 additions and 0 deletions

View file

@ -297,6 +297,7 @@
#![feature(extended_varargs_abi_support)] #![feature(extended_varargs_abi_support)]
#![feature(f128)] #![feature(f128)]
#![feature(f16)] #![feature(f16)]
#![feature(ffi_const)]
#![feature(formatting_options)] #![feature(formatting_options)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(intra_doc_pointers)] #![feature(intra_doc_pointers)]

View file

@ -59,11 +59,14 @@ unsafe extern "C" {
#[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")] #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")]
#[cfg_attr(target_os = "haiku", link_name = "_errnop")] #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
#[cfg_attr(target_os = "aix", link_name = "_Errno")] #[cfg_attr(target_os = "aix", link_name = "_Errno")]
// SAFETY: this will always return the same pointer on a given thread.
#[unsafe(ffi_const)]
fn errno_location() -> *mut c_int; fn errno_location() -> *mut c_int;
} }
/// Returns the platform-specific value of errno /// Returns the platform-specific value of errno
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
#[inline]
pub fn errno() -> i32 { pub fn errno() -> i32 {
unsafe { (*errno_location()) as i32 } unsafe { (*errno_location()) as i32 }
} }
@ -72,16 +75,19 @@ pub fn errno() -> i32 {
// needed for readdir and syscall! // needed for readdir and syscall!
#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))] #[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
#[allow(dead_code)] // but not all target cfgs actually end up using it #[allow(dead_code)] // but not all target cfgs actually end up using it
#[inline]
pub fn set_errno(e: i32) { pub fn set_errno(e: i32) {
unsafe { *errno_location() = e as c_int } unsafe { *errno_location() = e as c_int }
} }
#[cfg(target_os = "vxworks")] #[cfg(target_os = "vxworks")]
#[inline]
pub fn errno() -> i32 { pub fn errno() -> i32 {
unsafe { libc::errnoGet() } unsafe { libc::errnoGet() }
} }
#[cfg(target_os = "rtems")] #[cfg(target_os = "rtems")]
#[inline]
pub fn errno() -> i32 { pub fn errno() -> i32 {
unsafe extern "C" { unsafe extern "C" {
#[thread_local] #[thread_local]
@ -92,6 +98,7 @@ pub fn errno() -> i32 {
} }
#[cfg(target_os = "dragonfly")] #[cfg(target_os = "dragonfly")]
#[inline]
pub fn errno() -> i32 { pub fn errno() -> i32 {
unsafe extern "C" { unsafe extern "C" {
#[thread_local] #[thread_local]
@ -103,6 +110,7 @@ pub fn errno() -> i32 {
#[cfg(target_os = "dragonfly")] #[cfg(target_os = "dragonfly")]
#[allow(dead_code)] #[allow(dead_code)]
#[inline]
pub fn set_errno(e: i32) { pub fn set_errno(e: i32) {
unsafe extern "C" { unsafe extern "C" {
#[thread_local] #[thread_local]