|
@@ -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]
|