Skip to content

Commit 7e2cd68

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 85c53a9 commit 7e2cd68

File tree

2 files changed

+26
-20
lines changed

2 files changed

+26
-20
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
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

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,37 @@ pub fn pause() -> Result<()> {
366366
Errno::result(res).map(drop)
367367
}
368368

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

374-
#[cfg(feature = "execvpe")]
375-
use std::ffi::CString;
376400

377401
pub fn pivot_root<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
378402
new_root: &P1, put_old: &P2) -> Result<()> {
@@ -387,22 +411,5 @@ mod linux {
387411
Errno::result(res).map(drop)
388412
}
389413

390-
#[inline]
391-
#[cfg(feature = "execvpe")]
392-
pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<()> {
393-
use std::ptr;
394-
use libc::c_char;
395-
396-
let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
397-
args_p.push(ptr::null());
398-
399-
let mut env_p: Vec<*const c_char> = env.iter().map(|s| s.as_ptr()).collect();
400-
env_p.push(ptr::null());
401414

402-
unsafe {
403-
super::ffi::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
404-
};
405-
406-
Err(Error::Sys(Errno::last()))
407-
}
408415
}

0 commit comments

Comments
 (0)