From 6f80cd7bfc9b6141451a818daa4ac2fd9f4abad0 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 17 Jul 2017 18:37:54 -0700 Subject: [PATCH] redox: handle multiple paths in PATH --- src/libstd/sys/redox/os.rs | 6 ++--- src/libstd/sys/redox/process.rs | 37 +++++++++++++++++----------- src/libstd/sys/redox/syscall/call.rs | 6 ++--- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/libstd/sys/redox/os.rs b/src/libstd/sys/redox/os.rs index e38b7b29f48..efddd5f0294 100644 --- a/src/libstd/sys/redox/os.rs +++ b/src/libstd/sys/redox/os.rs @@ -73,10 +73,10 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths { fn bytes_to_path(b: &[u8]) -> PathBuf { PathBuf::from(::from_bytes(b)) } - fn is_colon(b: &u8) -> bool { *b == b':' } + fn is_semicolon(b: &u8) -> bool { *b == b';' } let unparsed = unparsed.as_bytes(); SplitPaths { - iter: unparsed.split(is_colon as fn(&u8) -> bool) + iter: unparsed.split(is_semicolon as fn(&u8) -> bool) .map(bytes_to_path as fn(&[u8]) -> PathBuf) } } @@ -94,7 +94,7 @@ pub fn join_paths(paths: I) -> Result where I: Iterator, T: AsRef { let mut joined = Vec::new(); - let sep = b':'; + let sep = b';'; for (i, path) in paths.enumerate() { let path = path.as_ref().as_bytes(); diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 62d873d257d..e7e66e57e13 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -9,11 +9,12 @@ // except according to those terms. use collections::hash_map::HashMap; -use env; +use env::{self, split_paths}; use ffi::OsStr; +use os::unix::ffi::OsStrExt; use fmt; use io::{self, Error, ErrorKind}; -use path::Path; +use path::{Path, PathBuf}; use sys::fd::FileDesc; use sys::fs::{File, OpenOptions}; use sys::pipe::{self, AnonPipe}; @@ -313,23 +314,29 @@ impl Command { } let program = if self.program.contains(':') || self.program.contains('/') { - self.program.to_owned() - } else { - let mut path_env = ::env::var("PATH").unwrap_or(".".to_string()); - - if ! path_env.ends_with('/') { - path_env.push('/'); + Some(PathBuf::from(&self.program)) + } else if let Ok(path_env) = ::env::var("PATH") { + let mut program = None; + for mut path in split_paths(&path_env) { + path.push(&self.program); + if path.exists() { + program = Some(path); + break; + } } - - path_env.push_str(&self.program); - - path_env + program + } else { + None }; - if let Err(err) = syscall::execve(&program, &args) { - io::Error::from_raw_os_error(err.errno as i32) + if let Some(program) = program { + if let Err(err) = syscall::execve(program.as_os_str().as_bytes(), &args) { + io::Error::from_raw_os_error(err.errno as i32) + } else { + panic!("return from exec without err"); + } } else { - panic!("return from exec without err"); + io::Error::new(io::ErrorKind::NotFound, "") } } diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs index fadf7325d75..ec9005c2cc3 100644 --- a/src/libstd/sys/redox/syscall/call.rs +++ b/src/libstd/sys/redox/syscall/call.rs @@ -77,9 +77,9 @@ pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result { } /// Replace the current process with a new executable -pub fn execve(path: &str, args: &[[usize; 2]]) -> Result { - unsafe { syscall4(SYS_EXECVE, path.as_ptr() as usize, path.len(), - args.as_ptr() as usize, args.len()) } +pub fn execve>(path: T, args: &[[usize; 2]]) -> Result { + unsafe { syscall4(SYS_EXECVE, path.as_ref().as_ptr() as usize, + path.as_ref().len(), args.as_ptr() as usize, args.len()) } } /// Exit the current process