Skip to content

Commit 45a4581

Browse files
committed
make execvpe available for all platforms
- execvpe is as GNU extension of libc. - redone in Rust to make it available on all systems. - this also makes the feature flag obsolete.
1 parent b7c2f88 commit 45a4581

File tree

2 files changed

+26
-20
lines changed

2 files changed

+26
-20
lines changed

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ build = "build.rs"
1818

1919
[features]
2020
eventfd = []
21-
execvpe = []
2221
preadv_pwritev = []
2322
signalfd = []
2423

src/unistd.rs

+26-19
Original file line numberDiff line numberDiff line change
@@ -373,13 +373,37 @@ pub fn sleep(seconds: libc::c_uint) -> c_uint {
373373
unsafe { libc::sleep(seconds) }
374374
}
375375

376+
pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<()> {
377+
use std::env;
378+
use std::ffi::OsString;
379+
use std::ffi::OsStr;
380+
use std::os::unix::ffi::OsStrExt;
381+
382+
if filename.as_bytes().iter().find(|c| **c == b'/').is_some() {
383+
return execve(filename, args, env);
384+
}
385+
386+
let paths = match env::var_os("PATH") {
387+
Some(val) => val,
388+
None => OsString::from("/usr/local/bin:/bin:/usr/bin"),
389+
};
390+
391+
let name = OsStr::from_bytes(&filename.as_bytes());
392+
let mut res = Err(Error::Sys(Errno::ENOENT));
393+
for path in env::split_paths(&paths) {
394+
let p = path.with_file_name(name);
395+
let p2 = &CString::new(p.as_os_str().as_bytes()).unwrap();
396+
res = execve(p2, args, env);
397+
}
398+
399+
return res;
400+
}
401+
376402
#[cfg(any(target_os = "linux", target_os = "android"))]
377403
mod linux {
378404
use sys::syscall::{syscall, SYSPIVOTROOT};
379405
use {Errno, Result, NixPath};
380406

381-
#[cfg(feature = "execvpe")]
382-
use std::ffi::CString;
383407

384408
pub fn pivot_root<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
385409
new_root: &P1, put_old: &P2) -> Result<()> {
@@ -394,22 +418,5 @@ mod linux {
394418
Errno::result(res).map(drop)
395419
}
396420

397-
#[inline]
398-
#[cfg(feature = "execvpe")]
399-
pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<()> {
400-
use std::ptr;
401-
use libc::c_char;
402-
403-
let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
404-
args_p.push(ptr::null());
405-
406-
let mut env_p: Vec<*const c_char> = env.iter().map(|s| s.as_ptr()).collect();
407-
env_p.push(ptr::null());
408421

409-
unsafe {
410-
super::ffi::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
411-
};
412-
413-
Err(Error::Sys(Errno::last()))
414-
}
415422
}

0 commit comments

Comments
 (0)