]> git.lizzy.rs Git - rust.git/blobdiff - src/libnative/io/process.rs
auto merge of #15999 : Kimundi/rust/fix_folder, r=nikomatsakis
[rust.git] / src / libnative / io / process.rs
index 71702d180b9e0efaffb630e01fcecb23803e1c65..c89a40d65135144f880d0904619392942793a434 100644 (file)
@@ -305,6 +305,25 @@ fn spawn_process_os(cfg: ProcessConfig,
         })
     }
 
+    // To have the spawning semantics of unix/windows stay the same, we need to
+    // read the *child's* PATH if one is provided. See #15149 for more details.
+    let program = cfg.env.and_then(|env| {
+        for &(ref key, ref v) in env.iter() {
+            if b"PATH" != key.as_bytes_no_nul() { continue }
+
+            // Split the value and test each path to see if the program exists.
+            for path in os::split_paths(v.as_bytes_no_nul()).move_iter() {
+                let path = path.join(cfg.program.as_bytes_no_nul())
+                               .with_extension(os::consts::EXE_EXTENSION);
+                if path.exists() {
+                    return Some(path.to_c_str())
+                }
+            }
+            break
+        }
+        None
+    });
+
     unsafe {
         let mut si = zeroed_startupinfo();
         si.cb = mem::size_of::<STARTUPINFO>() as DWORD;
@@ -362,7 +381,8 @@ fn spawn_process_os(cfg: ProcessConfig,
         try!(set_fd(&out_fd, &mut si.hStdOutput, false));
         try!(set_fd(&err_fd, &mut si.hStdError, false));
 
-        let cmd_str = make_command_line(cfg.program, cfg.args);
+        let cmd_str = make_command_line(program.as_ref().unwrap_or(cfg.program),
+                                        cfg.args);
         let mut pi = zeroed_process_information();
         let mut create_err = None;
 
@@ -729,7 +749,7 @@ fn with_argv<T>(prog: &CString, args: &[CString],
 }
 
 #[cfg(unix)]
-fn with_envp<T>(env: Option<&[(CString, CString)]>,
+fn with_envp<T>(env: Option<&[(&CString, &CString)]>,
                 cb: proc(*const c_void) -> T) -> T {
     // On posixy systems we can pass a char** for envp, which is a
     // null-terminated array of "k=v\0" strings. Since we must create
@@ -762,7 +782,7 @@ fn with_envp<T>(env: Option<&[(CString, CString)]>,
 }
 
 #[cfg(windows)]
-fn with_envp<T>(env: Option<&[(CString, CString)]>, cb: |*mut c_void| -> T) -> T {
+fn with_envp<T>(env: Option<&[(&CString, &CString)]>, cb: |*mut c_void| -> T) -> T {
     // On win32 we pass an "environment block" which is not a char**, but
     // rather a concatenation of null-terminated k=v\0 sequences, with a final
     // \0 to terminate.
@@ -827,6 +847,7 @@ pub fn WTERMSIG(status: i32) -> i32 { status & 0x7f }
     #[cfg(target_os = "macos")]
     #[cfg(target_os = "ios")]
     #[cfg(target_os = "freebsd")]
+    #[cfg(target_os = "dragonfly")]
     mod imp {
         pub fn WIFEXITED(status: i32) -> bool { (status & 0x7f) == 0 }
         pub fn WEXITSTATUS(status: i32) -> i32 { status >> 8 }