diff options
| author | Ian Douglas Scott <ian@iandouglasscott.com> | 2017-07-17 18:37:54 -0700 |
|---|---|---|
| committer | Ian Douglas Scott <ian@iandouglasscott.com> | 2017-07-17 19:17:48 -0700 |
| commit | 6f80cd7bfc9b6141451a818daa4ac2fd9f4abad0 (patch) | |
| tree | 2fc84acb6f6864a444dec7881b17e4dc5828af96 | |
| parent | 2652ce6771b114189cdc1f9bd026a10af0a714e0 (diff) | |
| download | rust-6f80cd7bfc9b6141451a818daa4ac2fd9f4abad0.tar.gz rust-6f80cd7bfc9b6141451a818daa4ac2fd9f4abad0.zip | |
redox: handle multiple paths in PATH
| -rw-r--r-- | src/libstd/sys/redox/os.rs | 6 | ||||
| -rw-r--r-- | src/libstd/sys/redox/process.rs | 37 | ||||
| -rw-r--r-- | 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(<OsStr as OsStrExt>::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<I, T>(paths: I) -> Result<OsString, JoinPathsError> where I: Iterator<Item=T>, T: AsRef<OsStr> { 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<usize> { } /// Replace the current process with a new executable -pub fn execve(path: &str, args: &[[usize; 2]]) -> Result<usize> { - unsafe { syscall4(SYS_EXECVE, path.as_ptr() as usize, path.len(), - args.as_ptr() as usize, args.len()) } +pub fn execve<T: AsRef<[u8]>>(path: T, args: &[[usize; 2]]) -> Result<usize> { + 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 |
