diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index 1218fab05f034..d1edea4df7105 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -40,6 +40,9 @@ pub struct Process { /// None until finish() is called. exit_code: Option, + + /// Manually delivered signal + exit_signal: Option, } impl Process { @@ -107,7 +110,12 @@ impl Process { match res { Ok(res) => { - Ok((Process { pid: res.pid, handle: res.handle, exit_code: None }, + Ok((Process { + pid: res.pid, + handle: res.handle, + exit_code: None, + exit_signal: None, + }, ret_io)) } Err(e) => Err(e) @@ -127,6 +135,14 @@ impl rtio::RtioProcess for Process { Some(code) => code, None => { let code = waitpid(self.pid); + // On windows, waitpid will never return a signal. If a signal + // was successfully delivered to the process, however, we can + // consider it as having died via a signal. + let code = match self.exit_signal { + None => code, + Some(signal) if cfg!(windows) => p::ExitSignal(signal), + Some(..) => code, + }; self.exit_code = Some(code); code } @@ -157,7 +173,14 @@ impl rtio::RtioProcess for Process { }), None => {} } - return unsafe { killpid(self.pid, signum) }; + + // A successfully delivered signal that isn't 0 (just a poll for being + // alive) is recorded for windows (see wait()) + match unsafe { killpid(self.pid, signum) } { + Ok(()) if signum == 0 => Ok(()), + Ok(()) => { self.exit_signal = Some(signum); Ok(()) } + Err(e) => Err(e), + } } } @@ -256,31 +279,37 @@ fn spawn_process_os(config: p::ProcessConfig, let cur_proc = GetCurrentProcess(); - let orig_std_in = get_osfhandle(in_fd) as HANDLE; - if orig_std_in == INVALID_HANDLE_VALUE as HANDLE { - fail!("failure in get_osfhandle: {}", os::last_os_error()); - } - if DuplicateHandle(cur_proc, orig_std_in, cur_proc, &mut si.hStdInput, - 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { - fail!("failure in DuplicateHandle: {}", os::last_os_error()); + if in_fd != -1 { + let orig_std_in = get_osfhandle(in_fd) as HANDLE; + if orig_std_in == INVALID_HANDLE_VALUE as HANDLE { + fail!("failure in get_osfhandle: {}", os::last_os_error()); + } + if DuplicateHandle(cur_proc, orig_std_in, cur_proc, &mut si.hStdInput, + 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { + fail!("failure in DuplicateHandle: {}", os::last_os_error()); + } } - let orig_std_out = get_osfhandle(out_fd) as HANDLE; - if orig_std_out == INVALID_HANDLE_VALUE as HANDLE { - fail!("failure in get_osfhandle: {}", os::last_os_error()); - } - if DuplicateHandle(cur_proc, orig_std_out, cur_proc, &mut si.hStdOutput, - 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { - fail!("failure in DuplicateHandle: {}", os::last_os_error()); + if out_fd != -1 { + let orig_std_out = get_osfhandle(out_fd) as HANDLE; + if orig_std_out == INVALID_HANDLE_VALUE as HANDLE { + fail!("failure in get_osfhandle: {}", os::last_os_error()); + } + if DuplicateHandle(cur_proc, orig_std_out, cur_proc, &mut si.hStdOutput, + 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { + fail!("failure in DuplicateHandle: {}", os::last_os_error()); + } } - let orig_std_err = get_osfhandle(err_fd) as HANDLE; - if orig_std_err == INVALID_HANDLE_VALUE as HANDLE { - fail!("failure in get_osfhandle: {}", os::last_os_error()); - } - if DuplicateHandle(cur_proc, orig_std_err, cur_proc, &mut si.hStdError, - 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { - fail!("failure in DuplicateHandle: {}", os::last_os_error()); + if err_fd != -1 { + let orig_std_err = get_osfhandle(err_fd) as HANDLE; + if orig_std_err == INVALID_HANDLE_VALUE as HANDLE { + fail!("failure in get_osfhandle: {}", os::last_os_error()); + } + if DuplicateHandle(cur_proc, orig_std_err, cur_proc, &mut si.hStdError, + 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { + fail!("failure in DuplicateHandle: {}", os::last_os_error()); + } } let cmd = make_command_line(config.program, config.args); @@ -307,9 +336,9 @@ fn spawn_process_os(config: p::ProcessConfig, }) }); - assert!(CloseHandle(si.hStdInput) != 0); - assert!(CloseHandle(si.hStdOutput) != 0); - assert!(CloseHandle(si.hStdError) != 0); + if in_fd != -1 { assert!(CloseHandle(si.hStdInput) != 0); } + if out_fd != -1 { assert!(CloseHandle(si.hStdOutput) != 0); } + if err_fd != -1 { assert!(CloseHandle(si.hStdError) != 0); } match create_err { Some(err) => return Err(err), diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index 123160f0c8022..1435a10111558 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[no_std]; +#![no_std] #[lang="fail_"] fn fail(_: *i8, _: *i8, _: uint) -> ! { loop {} } diff --git a/src/test/run-pass/lang-item-public.rs b/src/test/run-pass/lang-item-public.rs index 761e5d7eb4913..23e48b97427c5 100644 --- a/src/test/run-pass/lang-item-public.rs +++ b/src/test/run-pass/lang-item-public.rs @@ -10,8 +10,9 @@ // aux-build:lang-item-public.rs // ignore-android +// ignore-win32 #13361 -#[no_std]; +#![no_std] extern crate lang_lib = "lang-item-public"; diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index eff5682a55322..063ffed315127 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -16,10 +16,18 @@ #[phase(syntax, link)] extern crate log; extern crate libc; +extern crate green; +extern crate rustuv; use std::io::net::ip::{Ipv4Addr, SocketAddr}; use std::io::net::tcp::{TcpListener, TcpStream}; use std::io::{Acceptor, Listener}; +use std::task; + +#[start] +fn start(argc: int, argv: **u8) -> int { + green::start(argc, argv, rustuv::event_loop, main) +} fn main() { // This test has a chance to time out, try to not let it time out @@ -53,7 +61,9 @@ fn main() { let (tx, rx) = channel(); for _ in range(0, 1000) { let tx = tx.clone(); - spawn(proc() { + let mut builder = task::task(); + builder.opts.stack_size = Some(32 * 1024); + builder.spawn(proc() { match TcpStream::connect(addr) { Ok(stream) => { let mut stream = stream;