diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 2f2663db60769..fe428c85d3854 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -451,7 +451,7 @@ pub fn current_exe() -> io::Result { super::unsupported::unsupported() } -#[cfg(target_os = "fuchsia")] +#[cfg(any(target_os = "fuchsia", target_os = "aix"))] pub fn current_exe() -> io::Result { use crate::io::ErrorKind; @@ -468,7 +468,35 @@ pub fn current_exe() -> io::Result { let path = PathBuf::from(exe_path); // Prepend the current working directory to the path if it's not absolute. - if !path.is_absolute() { getcwd().map(|cwd| cwd.join(path)) } else { Ok(path) } + if cfg!(target_os = "fuchsia") { + if !path.is_absolute() { + return getcwd().map(|cwd| cwd.join(path)); + } else { + return Ok(path); + } + } + + if path.is_absolute() { + return path.canonicalize(); + } + + // Search PWD to infer current_exe. + if let Some(pstr) = path.to_str() && pstr.contains("/") { + return getcwd().map(|cwd| cwd.join(path))?.canonicalize(); + } + + // Search PATH to infer current_exe. + if let Some(p) = getenv(OsStr::from_bytes("PATH".as_bytes())) { + for search_path in split_paths(&p) { + let pb = search_path.join(&path); + if pb.is_file() && let Ok(metadata) = crate::fs::metadata(&pb) && + metadata.permissions().mode() & 0o111 != 0 { + return pb.canonicalize(); + } + } + } + + return Err(io::const_io_error!(ErrorKind::Uncategorized, "an executable path was not found")); } pub struct Env {