From 35df79520149487c33bca0c2c14aab0c0c8fd1d6 Mon Sep 17 00:00:00 2001 From: joboet Date: Mon, 22 Jun 2026 17:20:41 +0200 Subject: [PATCH 1/2] std: allocate less memory in `current_exe` for OpenBSD --- library/std/src/lib.rs | 1 + library/std/src/sys/paths/unix.rs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c9e884d89c85e..ed71db1209358 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -287,6 +287,7 @@ #![feature(doc_masked)] #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] +#![feature(exact_div)] #![feature(f16)] #![feature(f128)] #![feature(ffi_const)] diff --git a/library/std/src/sys/paths/unix.rs b/library/std/src/sys/paths/unix.rs index e0b1aafda6eb0..02b2890dcb90c 100644 --- a/library/std/src/sys/paths/unix.rs +++ b/library/std/src/sys/paths/unix.rs @@ -234,11 +234,20 @@ pub fn current_exe() -> io::Result { unsafe { let mut mib = [libc::CTL_KERN, libc::KERN_PROC_ARGS, libc::getpid(), libc::KERN_PROC_ARGV]; let mib = mib.as_mut_ptr(); - let mut argv_len = 0; - cvt(libc::sysctl(mib, 4, ptr::null_mut(), &mut argv_len, ptr::null_mut(), 0))?; - let mut argv = Vec::<*const libc::c_char>::with_capacity(argv_len as usize); - cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?; - argv.set_len(argv_len as usize); + + // Determine the required size (in bytes) for the argument array ... + let mut argv_size = 0; + cvt(libc::sysctl(mib, 4, ptr::null_mut(), &mut argv_size, ptr::null_mut(), 0))?; + + // ... allocate a buffer for it ... + let argc = argv_size.div_exact(size_of::<*const libc::c_char>()).unwrap(); + let mut argv = Vec::<*const libc::c_char>::with_capacity(argc); + + // ... and retrieve the argument array. + cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_size, ptr::null_mut(), 0))?; + let argc = argv_size.div_exact(size_of::<*const libc::c_char>()).unwrap(); + argv.set_len(argc); + if argv[0].is_null() { return Err(io::const_error!(io::ErrorKind::Uncategorized, "no current exe available")); } From db9b6a1d7d868086f3cab2afa37040a20f2bfe31 Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 25 Jun 2026 14:48:59 +0200 Subject: [PATCH 2/2] std: program names starting with a dot may not be path-like --- library/std/src/sys/paths/unix.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/paths/unix.rs b/library/std/src/sys/paths/unix.rs index 02b2890dcb90c..3f3fca5dcf8be 100644 --- a/library/std/src/sys/paths/unix.rs +++ b/library/std/src/sys/paths/unix.rs @@ -252,9 +252,13 @@ pub fn current_exe() -> io::Result { return Err(io::const_error!(io::ErrorKind::Uncategorized, "no current exe available")); } let argv0 = CStr::from_ptr(argv[0]).to_bytes(); - if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') { + if argv0.iter().any(|b| *b == b'/') { + // The program name is path-like, so try to canonicalize it. crate::fs::canonicalize(OsStr::from_bytes(argv0)) } else { + // The program was probably found in the PATH. Instead of trying to + // find it again (which might not succeed if PATH has changed), just + // return the program name – this function is best-effort anyway. Ok(PathBuf::from(OsStr::from_bytes(argv0))) } }