redox: handle multiple paths in PATH

This commit is contained in:
Ian Douglas Scott 2017-07-17 18:37:54 -07:00
parent 2652ce6771
commit 6f80cd7bfc
No known key found for this signature in database
GPG Key ID: 4924E10E199B5959
3 changed files with 28 additions and 21 deletions

View File

@ -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();

View File

@ -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, "")
}
}

View File

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