Some(..) => return Err(IoError {
code: ERROR as uint,
extra: 0,
- detail: Some("can't kill an exited process".to_str()),
+ detail: Some("can't kill an exited process".to_string()),
}),
None => {}
}
return Err(IoError {
code: libc::ERROR_CALL_NOT_IMPLEMENTED as uint,
extra: 0,
- detail: Some("unsupported gid/uid requested on windows".to_str()),
+ detail: Some("unsupported gid/uid requested on windows".to_string()),
})
}
+ // 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;
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;
}
#[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
}
#[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.
#[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 }
// which will wake up the other end at some point, so we just allow this
// signal to be coalesced with the pending signals on the pipe.
extern fn sigchld_handler(_signum: libc::c_int) {
- let msg = 1;
+ let msg = 1i;
match unsafe {
libc::write(WRITE_FD, &msg as *const _ as *const libc::c_void, 1)
} {