diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index 3a6ae42f946..7a0c1c35d65 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -583,10 +583,11 @@ fn spawn_process_os(cfg: ProcessConfig, let mut bytes = [0, ..4]; return match input.inner_read(bytes) { Ok(4) => { - let errno = (bytes[0] << 24) as i32 | - (bytes[1] << 16) as i32 | - (bytes[2] << 8) as i32 | - (bytes[3] << 0) as i32; + let errno = (bytes[0] as i32 << 24) | + (bytes[1] as i32 << 16) | + (bytes[2] as i32 << 8) | + (bytes[3] as i32 << 0); + Err(IoError { code: errno as uint, detail: None, @@ -637,10 +638,10 @@ fn spawn_process_os(cfg: ProcessConfig, fn fail(output: &mut file::FileDesc) -> ! { let errno = os::errno(); let bytes = [ - (errno << 24) as u8, - (errno << 16) as u8, - (errno << 8) as u8, - (errno << 0) as u8, + (errno >> 24) as u8, + (errno >> 16) as u8, + (errno >> 8) as u8, + (errno >> 0) as u8, ]; assert!(output.inner_write(bytes).is_ok()); unsafe { libc::_exit(1) } diff --git a/src/test/run-pass/unix-process-spawn-errno.rs b/src/test/run-pass/unix-process-spawn-errno.rs new file mode 100644 index 00000000000..555bf2cd4c0 --- /dev/null +++ b/src/test/run-pass/unix-process-spawn-errno.rs @@ -0,0 +1,94 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-windows + +#![feature(macro_rules)] + +extern crate native; +extern crate rustrt; +extern crate libc; +use libc::{c_char, c_int}; +use native::io::process; +use rustrt::rtio; +use rustrt::c_str; + +macro_rules! c_string { + ($s:expr) => { { + let ptr = concat!($s, "\0").as_ptr() as *const i8; + unsafe { &c_str::CString::new(ptr, false) } + } } +} + +static EXPECTED_ERRNO: c_int = 0x778899aa; + +#[no_mangle] +pub unsafe extern "C" fn chdir(_: *const c_char) -> c_int { + // copied from std::os::errno() + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd"))] + fn errno_location() -> *mut c_int { + extern { + fn __error() -> *mut c_int; + } + unsafe { + __error() + } + } + + #[cfg(target_os = "dragonfly")] + fn errno_location() -> *mut c_int { + extern { + fn __dfly_error() -> *mut c_int; + } + unsafe { + __dfly_error() + } + } + + #[cfg(any(target_os = "linux", target_os = "android"))] + fn errno_location() -> *mut c_int { + extern { + fn __errno_location() -> *mut c_int; + } + unsafe { + __errno_location() + } + } + + *errno_location() = EXPECTED_ERRNO; + return -1; +} + +fn main() { + let program = c_string!("true"); + let cwd = c_string!("whatever"); + let cfg = rtio::ProcessConfig { + program: program, + args: &[], + env: None, + cwd: Some(cwd), + stdin: rtio::Ignored, + stdout: rtio::Ignored, + stderr: rtio::Ignored, + extra_io: &[], + uid: None, + gid: None, + detach: false + }; + + match process::Process::spawn(cfg) { + Ok(_) => { fail!("spawn() should have failled"); } + Err(rtio::IoError { code: err, ..}) => { + assert_eq!(err as c_int, EXPECTED_ERRNO); + } + }; +}