redox: handle multiple paths in PATH
This commit is contained in:
parent
2652ce6771
commit
6f80cd7bfc
@ -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();
|
||||
|
@ -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, "")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user