diff --git a/Cargo.toml b/Cargo.toml index 2f2663ada1..f2e213ae03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,6 @@ build = "build.rs" [features] eventfd = [] -execvpe = [] preadv_pwritev = [] signalfd = [] diff --git a/src/unistd.rs b/src/unistd.rs index 4a7359cccc..c03a04d676 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -366,13 +366,37 @@ pub fn pause() -> Result<()> { Errno::result(res).map(drop) } +pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<()> { + use std::env; + use std::ffi::OsString; + use std::ffi::OsStr; + use std::os::unix::ffi::OsStrExt; + + if filename.as_bytes().iter().find(|c| **c == b'/').is_some() { + return execve(filename, args, env); + } + + let paths = match env::var_os("PATH") { + Some(val) => val, + None => OsString::from("/usr/local/bin:/bin:/usr/bin"), + }; + + let name = OsStr::from_bytes(&filename.as_bytes()); + let mut res = Err(Error::Sys(Errno::ENOENT)); + for path in env::split_paths(&paths) { + let p = path.with_file_name(name); + let p2 = &CString::new(p.as_os_str().as_bytes()).unwrap(); + res = execve(p2, args, env); + } + + return res; +} + #[cfg(any(target_os = "linux", target_os = "android"))] mod linux { use sys::syscall::{syscall, SYSPIVOTROOT}; use {Errno, Result, NixPath}; - #[cfg(feature = "execvpe")] - use std::ffi::CString; pub fn pivot_root( new_root: &P1, put_old: &P2) -> Result<()> { @@ -387,22 +411,5 @@ mod linux { Errno::result(res).map(drop) } - #[inline] - #[cfg(feature = "execvpe")] - pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<()> { - use std::ptr; - use libc::c_char; - - let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect(); - args_p.push(ptr::null()); - - let mut env_p: Vec<*const c_char> = env.iter().map(|s| s.as_ptr()).collect(); - env_p.push(ptr::null()); - unsafe { - super::ffi::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) - }; - - Err(Error::Sys(Errno::last())) - } }