Add execvp

This commit is contained in:
Jeremy Soller
2018-11-16 21:07:24 -07:00
parent dd65d0c0c8
commit a29aa9f599
2 changed files with 48 additions and 3 deletions
+38 -3
View File
@@ -3,7 +3,9 @@
use core::{ptr, slice};
use c_str::CStr;
use header::errno;
use header::limits;
use header::stdlib::getenv;
use header::time::timespec;
use platform;
use platform::types::*;
@@ -150,9 +152,42 @@ pub unsafe extern "C" fn execve(
Sys::execve(path, argv, envp)
}
// #[no_mangle]
pub extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -> c_int {
unimplemented!();
#[cfg(target_os = "linux")]
const PATH_SEPARATOR: u8 = b':';
#[cfg(target_os = "redox")]
const PATH_SEPARATOR: u8 = b';';
#[no_mangle]
pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -> c_int {
let file = CStr::from_ptr(file);
if file.to_bytes().contains(&b'/') || (cfg!(target_os = "redox") && file.to_bytes().contains(&b':')) {
execv(file.as_ptr(), argv)
} else {
let mut error = errno::ENOENT;
let path_env = getenv(c_str!("PATH\0").as_ptr());
if ! path_env.is_null() {
let path_env = CStr::from_ptr(path_env);
for mut path in path_env.to_bytes().split(|&b| b == PATH_SEPARATOR) {
let mut program = path.to_vec();
program.extend_from_slice(file.to_bytes());
program.push(b'0');
let program_c = CStr::from_bytes_with_nul(&program).unwrap();
execv(program_c.as_ptr(), argv);
match platform::errno {
errno::ENOENT => (),
other => error = other,
}
}
}
platform::errno = error;
-1
}
}
#[no_mangle]
+10
View File
@@ -1,3 +1,13 @@
#[macro_export]
macro_rules! c_str {
($lit:expr) => {
unsafe {
$crate::c_str::CStr::from_ptr(concat!($lit, "\0").as_ptr()
as *const $crate::platform::types::c_char)
}
}
}
/// Print to stdout
#[macro_export]
macro_rules! print {