]> git.lizzy.rs Git - rust.git/commitdiff
redox: handle multiple paths in PATH
authorIan Douglas Scott <ian@iandouglasscott.com>
Tue, 18 Jul 2017 01:37:54 +0000 (18:37 -0700)
committerIan Douglas Scott <ian@iandouglasscott.com>
Tue, 18 Jul 2017 02:17:48 +0000 (19:17 -0700)
src/libstd/sys/redox/os.rs
src/libstd/sys/redox/process.rs
src/libstd/sys/redox/syscall/call.rs

index e38b7b29f4837e1de389bb51722d245ba78c62c7..efddd5f0294840afb40a94b8f627d5d23e4138e6 100644 (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();
index 62d873d257d8ffcd7651af05640a1266b667d5b1..e7e66e57e13acd5b316972534b0adcb1c7a22513 100644 (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 @@ macro_rules! t {
         }
 
         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, "")
         }
     }
 
index fadf7325d75757e92862db585af20acf5b782d63..ec9005c2cc3be702981a2febe47b20fc5307fe18 100644 (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