diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0d0d9e0759d82..aa51e9e6b06be 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -287,7 +287,6 @@ #![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 cee799c36c79b..756c5ec26f127 100644 --- a/library/std/src/sys/paths/unix.rs +++ b/library/std/src/sys/paths/unix.rs @@ -253,37 +253,14 @@ pub fn current_exe() -> io::Result { #[cfg(target_os = "openbsd")] pub fn current_exe() -> io::Result { + let mut path = vec![0u8; libc::PATH_MAX as usize]; unsafe { - let mut mib = [libc::CTL_KERN, libc::KERN_PROC_ARGS, libc::getpid(), libc::KERN_PROC_ARGV]; - let mib = mib.as_mut_ptr(); - - // 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")); - } - let argv0 = CStr::from_ptr(argv[0]).to_bytes(); - 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))) - } + cvt(libc::getexecpath(path.as_mut_ptr().cast(), path.len()))?; + // SAFETY: getexecpath(3) NUL-terminates the buffer on success. + let len = CStr::from_ptr(path.as_ptr().cast()).count_bytes(); + path.truncate(len); } + Ok(PathBuf::from(OsString::from_vec(path))) } #[cfg(any(