redox: handle multiple paths in PATH
This commit is contained in:
@@ -73,10 +73,10 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths {
|
|||||||
fn bytes_to_path(b: &[u8]) -> PathBuf {
|
fn bytes_to_path(b: &[u8]) -> PathBuf {
|
||||||
PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
|
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();
|
let unparsed = unparsed.as_bytes();
|
||||||
SplitPaths {
|
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)
|
.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>
|
where I: Iterator<Item=T>, T: AsRef<OsStr>
|
||||||
{
|
{
|
||||||
let mut joined = Vec::new();
|
let mut joined = Vec::new();
|
||||||
let sep = b':';
|
let sep = b';';
|
||||||
|
|
||||||
for (i, path) in paths.enumerate() {
|
for (i, path) in paths.enumerate() {
|
||||||
let path = path.as_ref().as_bytes();
|
let path = path.as_ref().as_bytes();
|
||||||
|
|||||||
@@ -9,11 +9,12 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use collections::hash_map::HashMap;
|
use collections::hash_map::HashMap;
|
||||||
use env;
|
use env::{self, split_paths};
|
||||||
use ffi::OsStr;
|
use ffi::OsStr;
|
||||||
|
use os::unix::ffi::OsStrExt;
|
||||||
use fmt;
|
use fmt;
|
||||||
use io::{self, Error, ErrorKind};
|
use io::{self, Error, ErrorKind};
|
||||||
use path::Path;
|
use path::{Path, PathBuf};
|
||||||
use sys::fd::FileDesc;
|
use sys::fd::FileDesc;
|
||||||
use sys::fs::{File, OpenOptions};
|
use sys::fs::{File, OpenOptions};
|
||||||
use sys::pipe::{self, AnonPipe};
|
use sys::pipe::{self, AnonPipe};
|
||||||
@@ -313,23 +314,29 @@ impl Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let program = if self.program.contains(':') || self.program.contains('/') {
|
let program = if self.program.contains(':') || self.program.contains('/') {
|
||||||
self.program.to_owned()
|
Some(PathBuf::from(&self.program))
|
||||||
} else {
|
} else if let Ok(path_env) = ::env::var("PATH") {
|
||||||
let mut path_env = ::env::var("PATH").unwrap_or(".".to_string());
|
let mut program = None;
|
||||||
|
for mut path in split_paths(&path_env) {
|
||||||
if ! path_env.ends_with('/') {
|
path.push(&self.program);
|
||||||
path_env.push('/');
|
if path.exists() {
|
||||||
|
program = Some(path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
program
|
||||||
path_env.push_str(&self.program);
|
} else {
|
||||||
|
None
|
||||||
path_env
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = syscall::execve(&program, &args) {
|
if let Some(program) = program {
|
||||||
io::Error::from_raw_os_error(err.errno as i32)
|
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 {
|
} 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
|
/// Replace the current process with a new executable
|
||||||
pub fn execve(path: &str, args: &[[usize; 2]]) -> Result<usize> {
|
pub fn execve<T: AsRef<[u8]>>(path: T, args: &[[usize; 2]]) -> Result<usize> {
|
||||||
unsafe { syscall4(SYS_EXECVE, path.as_ptr() as usize, path.len(),
|
unsafe { syscall4(SYS_EXECVE, path.as_ref().as_ptr() as usize,
|
||||||
args.as_ptr() as usize, args.len()) }
|
path.as_ref().len(), args.as_ptr() as usize, args.len()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exit the current process
|
/// Exit the current process
|
||||||
|
|||||||
Reference in New Issue
Block a user