diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index da21db6e5d5f3..e86309f81af43 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -19,6 +19,8 @@ extern crate test; extern crate getopts; #[phase(link, syntax)] extern crate log; +extern crate green; +extern crate rustuv; use std::os; use std::io; @@ -41,6 +43,9 @@ pub mod runtest; pub mod common; pub mod errors; +#[start] +fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) } + pub fn main() { let args = os::args(); let config = parse_config(args.move_iter().collect()); diff --git a/src/driver/driver.rs b/src/driver/driver.rs index 0ceb12064b0eb..bd7096cda036d 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[no_uv]; +#[no_uv]; // remove this after stage0 +#[allow(attribute_usage)]; // remove this after stage0 +extern crate native; // remove this after stage0 #[cfg(rustdoc)] extern crate this = "rustdoc"; @@ -16,7 +18,9 @@ extern crate this = "rustdoc"; #[cfg(rustc)] extern crate this = "rustc"; -extern crate native; +#[cfg(not(stage0))] +fn main() { this::main() } +#[cfg(stage0)] #[start] fn start(argc: int, argv: **u8) -> int { native::start(argc, argv, this::main) } diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index b9846c9c3a2a8..926b9028a7a2d 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -209,7 +209,7 @@ pub mod stack; pub mod task; #[lang = "start"] -#[cfg(not(test))] +#[cfg(not(test), stage0)] pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int { use std::cast; start(argc, argv, proc() { diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs index f50cf72786475..afe440cc1e0c5 100644 --- a/src/libnative/lib.rs +++ b/src/libnative/lib.rs @@ -58,6 +58,7 @@ use std::os; use std::rt; +use std::str; pub mod io; pub mod task; @@ -68,6 +69,16 @@ static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20; #[cfg(unix, not(android))] static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20); +#[lang = "start"] +#[cfg(not(test), not(stage0))] +pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int { + use std::cast; + start(argc, argv, proc() { + let main: extern "Rust" fn() = unsafe { cast::transmute(main) }; + main(); + }) +} + /// Executes the given procedure after initializing the runtime with the given /// argc/argv. /// @@ -90,7 +101,12 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int { rt::init(argc, argv); let mut exit_code = None; let mut main = Some(main); - let t = task::new((my_stack_bottom, my_stack_top)).run(|| { + let mut task = task::new((my_stack_bottom, my_stack_top)); + task.name = Some(str::Slice("
")); + let t = task.run(|| { + unsafe { + rt::stack::record_stack_bounds(my_stack_bottom, my_stack_top); + } exit_code = Some(run(main.take_unwrap())); }); drop(t); diff --git a/src/librand/os.rs b/src/librand/os.rs index 0b11cfb0ac60d..0f4169bfe28cd 100644 --- a/src/librand/os.rs +++ b/src/librand/os.rs @@ -11,124 +11,178 @@ //! Interfaces to the operating system provided random number //! generators. -use Rng; +pub use self::imp::OSRng; #[cfg(unix)] -use reader::ReaderRng; -#[cfg(unix)] -use std::io::File; - -#[cfg(windows)] -use std::cast; -#[cfg(windows)] -use std::libc::{c_long, DWORD, BYTE}; -#[cfg(windows)] -type HCRYPTPROV = c_long; -// the extern functions imported from the runtime on Windows are -// implemented so that they either succeed or abort(), so we can just -// assume they work when we call them. - -/// A random number generator that retrieves randomness straight from -/// the operating system. Platform sources: -/// -/// - Unix-like systems (Linux, Android, Mac OSX): read directly from -/// `/dev/urandom`. -/// - Windows: calls `CryptGenRandom`, using the default cryptographic -/// service provider with the `PROV_RSA_FULL` type. -/// -/// This does not block. -#[cfg(unix)] -pub struct OSRng { - priv inner: ReaderRng -} -/// A random number generator that retrieves randomness straight from -/// the operating system. Platform sources: -/// -/// - Unix-like systems (Linux, Android, Mac OSX): read directly from -/// `/dev/urandom`. -/// - Windows: calls `CryptGenRandom`, using the default cryptographic -/// service provider with the `PROV_RSA_FULL` type. -/// -/// This does not block. -#[cfg(windows)] -pub struct OSRng { - priv hcryptprov: HCRYPTPROV -} - -impl OSRng { - /// Create a new `OSRng`. +mod imp { + use Rng; + use reader::ReaderRng; + use std::io::File; + + /// A random number generator that retrieves randomness straight from + /// the operating system. Platform sources: + /// + /// - Unix-like systems (Linux, Android, Mac OSX): read directly from + /// `/dev/urandom`. + /// - Windows: calls `CryptGenRandom`, using the default cryptographic + /// service provider with the `PROV_RSA_FULL` type. + /// + /// This does not block. #[cfg(unix)] - pub fn new() -> OSRng { - let reader = File::open(&Path::new("/dev/urandom")); - let reader = reader.ok().expect("Error opening /dev/urandom"); - let reader_rng = ReaderRng::new(reader); - - OSRng { inner: reader_rng } + pub struct OSRng { + priv inner: ReaderRng } - /// Create a new `OSRng`. - #[cfg(windows)] - pub fn new() -> OSRng { - extern { fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV); } + impl OSRng { + /// Create a new `OSRng`. + pub fn new() -> OSRng { + let reader = File::open(&Path::new("/dev/urandom")); + let reader = reader.ok().expect("Error opening /dev/urandom"); + let reader_rng = ReaderRng::new(reader); - let mut hcp = 0; - unsafe {rust_win32_rand_acquire(&mut hcp)}; - - OSRng { hcryptprov: hcp } + OSRng { inner: reader_rng } + } } -} -#[cfg(unix)] -impl Rng for OSRng { - fn next_u32(&mut self) -> u32 { - self.inner.next_u32() - } - fn next_u64(&mut self) -> u64 { - self.inner.next_u64() - } - fn fill_bytes(&mut self, v: &mut [u8]) { - self.inner.fill_bytes(v) + impl Rng for OSRng { + fn next_u32(&mut self) -> u32 { + self.inner.next_u32() + } + fn next_u64(&mut self) -> u64 { + self.inner.next_u64() + } + fn fill_bytes(&mut self, v: &mut [u8]) { + self.inner.fill_bytes(v) + } } } #[cfg(windows)] -impl Rng for OSRng { - fn next_u32(&mut self) -> u32 { - let mut v = [0u8, .. 4]; - self.fill_bytes(v); - unsafe { cast::transmute(v) } - } - fn next_u64(&mut self) -> u64 { - let mut v = [0u8, .. 8]; - self.fill_bytes(v); - unsafe { cast::transmute(v) } +mod imp { + use Rng; + use std::cast; + use std::libc::{c_ulong, DWORD, BYTE, LPCSTR, BOOL}; + use std::os; + use std::rt::stack; + + type HCRYPTPROV = c_ulong; + + /// A random number generator that retrieves randomness straight from + /// the operating system. Platform sources: + /// + /// - Unix-like systems (Linux, Android, Mac OSX): read directly from + /// `/dev/urandom`. + /// - Windows: calls `CryptGenRandom`, using the default cryptographic + /// service provider with the `PROV_RSA_FULL` type. + /// + /// This does not block. + pub struct OSRng { + priv hcryptprov: HCRYPTPROV } - fn fill_bytes(&mut self, v: &mut [u8]) { - extern { - fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD, - pbBuffer: *mut BYTE); - } - unsafe {rust_win32_rand_gen(self.hcryptprov, v.len() as DWORD, v.as_mut_ptr())} + static PROV_RSA_FULL: DWORD = 1; + static CRYPT_SILENT: DWORD = 64; + static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000; + static NTE_BAD_SIGNATURE: DWORD = 0x80090006; + + extern "system" { + fn CryptAcquireContextA(phProv: *mut HCRYPTPROV, + pszContainer: LPCSTR, + pszProvider: LPCSTR, + dwProvType: DWORD, + dwFlags: DWORD) -> BOOL; + fn CryptGenRandom(hProv: HCRYPTPROV, + dwLen: DWORD, + pbBuffer: *mut BYTE) -> BOOL; + fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL; } -} -impl Drop for OSRng { - #[cfg(unix)] - fn drop(&mut self) { - // ensure that OSRng is not implicitly copyable on all - // platforms, for consistency. + impl OSRng { + /// Create a new `OSRng`. + pub fn new() -> OSRng { + let mut hcp = 0; + let mut ret = unsafe { + CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR, + PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT) + }; + + // It turns out that if we can't acquire a context with the + // NTE_BAD_SIGNATURE error code, the documentation states: + // + // The provider DLL signature could not be verified. Either the + // DLL or the digital signature has been tampered with. + // + // Sounds fishy, no? As it turns out, our signature can be bad + // because our Thread Information Block (TIB) isn't exactly what it + // expects. As to why, I have no idea. The only data we store in the + // TIB is the stack limit for each thread, but apparently that's + // enough to make the signature valid. + // + // Furthermore, this error only happens the *first* time we call + // CryptAcquireContext, so we don't have to worry about future + // calls. + // + // Anyway, the fix employed here is that if we see this error, we + // pray that we're not close to the end of the stack, temporarily + // set the stack limit to 0 (what the TIB originally was), acquire a + // context, and then reset the stack limit. + // + // Again, I'm not sure why this is the fix, nor why we're getting + // this error. All I can say is that this seems to allow libnative + // to progress where it otherwise would be hindered. Who knew? + if ret == 0 && os::errno() as DWORD == NTE_BAD_SIGNATURE { + unsafe { + let limit = stack::get_sp_limit(); + stack::record_sp_limit(0); + ret = CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR, + PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT); + stack::record_sp_limit(limit); + } + } + + if ret == 0 { + fail!("couldn't create context: {}", os::last_os_error()); + } + OSRng { hcryptprov: hcp } + } } - #[cfg(windows)] - fn drop(&mut self) { - extern { fn rust_win32_rand_release(hProv: HCRYPTPROV); } + impl Rng for OSRng { + fn next_u32(&mut self) -> u32 { + let mut v = [0u8, .. 4]; + self.fill_bytes(v); + unsafe { cast::transmute(v) } + } + fn next_u64(&mut self) -> u64 { + let mut v = [0u8, .. 8]; + self.fill_bytes(v); + unsafe { cast::transmute(v) } + } + fn fill_bytes(&mut self, v: &mut [u8]) { + let ret = unsafe { + CryptGenRandom(self.hcryptprov, v.len() as DWORD, + v.as_mut_ptr()) + }; + if ret == 0 { + fail!("couldn't generate random bytes: {}", os::last_os_error()); + } + } + } - unsafe {rust_win32_rand_release(self.hcryptprov)} + impl Drop for OSRng { + fn drop(&mut self) { + let ret = unsafe { + CryptReleaseContext(self.hcryptprov, 0) + }; + if ret == 0 { + fail!("couldn't release context: {}", os::last_os_error()); + } + } } } - #[cfg(test)] mod test { use super::OSRng; diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 6a6819ae516d1..a78f90cbe8704 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -46,8 +46,8 @@ fn use_std(krate: &ast::Crate) -> bool { !attr::contains_name(krate.attrs.as_slice(), "no_std") } -fn use_uv(krate: &ast::Crate) -> bool { - !attr::contains_name(krate.attrs.as_slice(), "no_uv") +fn use_start(krate: &ast::Crate) -> bool { + !attr::contains_name(krate.attrs.as_slice(), "no_start") } fn no_prelude(attrs: &[ast::Attribute]) -> bool { @@ -87,18 +87,10 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> { span: DUMMY_SP }); - if use_uv(&krate) && !self.sess.building_library.get() { + if use_start(&krate) && !self.sess.building_library.get() { vis.push(ast::ViewItem { - node: ast::ViewItemExternCrate(token::str_to_ident("green"), - with_version("green"), - ast::DUMMY_NODE_ID), - attrs: Vec::new(), - vis: ast::Inherited, - span: DUMMY_SP - }); - vis.push(ast::ViewItem { - node: ast::ViewItemExternCrate(token::str_to_ident("rustuv"), - with_version("rustuv"), + node: ast::ViewItemExternCrate(token::str_to_ident("native"), + with_version("native"), ast::DUMMY_NODE_ID), attrs: Vec::new(), vis: ast::Inherited, diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 6c13d496166ae..286ecbd6c8f3c 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -961,7 +961,7 @@ fn check_heap_item(cx: &Context, it: &ast::Item) { } static crate_attrs: &'static [&'static str] = &[ - "crate_type", "feature", "no_uv", "no_main", "no_std", "crate_id", + "crate_type", "feature", "no_start", "no_main", "no_std", "crate_id", "desc", "comment", "license", "copyright", // not used in rustc now ]; diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index ee4f15e7954bd..42ccdaf956282 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -45,6 +45,7 @@ via `close` and `delete` methods. #[allow(deprecated_owned_vector)]; // NOTE: remove after stage0 #[cfg(test)] extern crate green; +#[cfg(test)] extern crate realrustuv = "rustuv"; use std::cast; use std::fmt; @@ -69,6 +70,16 @@ pub use self::signal::SignalWatcher; pub use self::timer::TimerWatcher; pub use self::tty::TtyWatcher; +// Run tests with libgreen instead of libnative. +// +// FIXME: This egregiously hacks around starting the test runner in a different +// threading mode than the default by reaching into the auto-generated +// '__test' module. +#[cfg(test)] #[start] +fn start(argc: int, argv: **u8) -> int { + green::start(argc, argv, __test::main) +} + mod macros; mod access; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 433400cc9f0e8..7d734469b1293 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -81,6 +81,16 @@ #[cfg(stage0)] pub use vec_ng = vec; +// Run tests with libgreen instead of libnative. +// +// FIXME: This egregiously hacks around starting the test runner in a different +// threading mode than the default by reaching into the auto-generated +// '__test' module. +#[cfg(test)] #[start] +fn start(argc: int, argv: **u8) -> int { + green::start(argc, argv, __test::main) +} + pub mod macros; mod rtdeps; diff --git a/src/rt/rust_builtin.c b/src/rt/rust_builtin.c index 8ab8636aa3a28..9c27fe1c5e446 100644 --- a/src/rt/rust_builtin.c +++ b/src/rt/rust_builtin.c @@ -387,65 +387,6 @@ rust_unset_sigprocmask() { #endif -#if defined(__WIN32__) -void -win32_require(LPCTSTR fn, BOOL ok) { - if (!ok) { - LPTSTR buf; - DWORD err = GetLastError(); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &buf, 0, NULL ); - fprintf(stderr, "%s failed with error %ld: %s", fn, err, buf); - LocalFree((HLOCAL)buf); - abort(); - } -} - -void -rust_win32_rand_acquire(HCRYPTPROV* phProv) { - win32_require - (_T("CryptAcquireContext"), - // changes to the parameters here should be reflected in the docs of - // rand::os::OSRng - CryptAcquireContext(phProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT|CRYPT_SILENT)); - -} -void -rust_win32_rand_gen(HCRYPTPROV hProv, DWORD dwLen, BYTE* pbBuffer) { - win32_require - (_T("CryptGenRandom"), CryptGenRandom(hProv, dwLen, pbBuffer)); -} -void -rust_win32_rand_release(HCRYPTPROV hProv) { - win32_require - (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0)); -} - -#else - -// these symbols are listed in rustrt.def.in, so they need to exist; but they -// should never be called. - -void -rust_win32_rand_acquire() { - abort(); -} -void -rust_win32_rand_gen() { - abort(); -} -void -rust_win32_rand_release() { - abort(); -} - -#endif - // // Local Variables: // mode: C++ diff --git a/src/test/run-fail/native-failure.rs b/src/test/run-fail/native-failure.rs index da00bdf5e0aef..377057a75ff1f 100644 --- a/src/test/run-fail/native-failure.rs +++ b/src/test/run-fail/native-failure.rs @@ -11,8 +11,6 @@ // ignore-android (FIXME #11419) // error-pattern:explicit failure -#[no_uv]; - extern crate native; #[start] diff --git a/src/test/run-make/bootstrap-from-c-with-green/lib.rs b/src/test/run-make/bootstrap-from-c-with-green/lib.rs index 920474ea9bd58..62c5a06dbbf7b 100644 --- a/src/test/run-make/bootstrap-from-c-with-green/lib.rs +++ b/src/test/run-make/bootstrap-from-c-with-green/lib.rs @@ -10,7 +10,6 @@ #[crate_id="boot#0.1"]; #[crate_type="dylib"]; -#[no_uv]; extern crate rustuv; extern crate green; diff --git a/src/test/run-make/bootstrap-from-c-with-native/lib.rs b/src/test/run-make/bootstrap-from-c-with-native/lib.rs index 2bc0dbb777031..33c8d4ffab7a8 100644 --- a/src/test/run-make/bootstrap-from-c-with-native/lib.rs +++ b/src/test/run-make/bootstrap-from-c-with-native/lib.rs @@ -10,7 +10,6 @@ #[crate_id="boot#0.1"]; #[crate_type="dylib"]; -#[no_uv]; extern crate native; diff --git a/src/test/run-pass/capturing-logging.rs b/src/test/run-pass/capturing-logging.rs index b1db8ad922332..97dfbb0d8e272 100644 --- a/src/test/run-pass/capturing-logging.rs +++ b/src/test/run-pass/capturing-logging.rs @@ -14,10 +14,9 @@ #[feature(phase)]; -#[no_uv]; -extern crate native; #[phase(syntax, link)] extern crate log; +extern crate native; use std::fmt; use std::io::{ChanReader, ChanWriter}; diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index db7b2803c7116..bda7a30762a1e 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -9,19 +9,50 @@ // except according to those terms. // ignore-fast +// ignore-pretty // compile-flags:--test // NB: These tests kill child processes. Valgrind sees these children as leaking // memory, which makes for some *confusing* logs. That's why these are here // instead of in std. -use std::io::timer; -use std::libc; -use std::str; -use std::io::process::{Process, ProcessOutput}; +#[feature(macro_rules)]; -#[test] -fn test_destroy_once() { +extern crate native; +extern crate green; +extern crate rustuv; + +macro_rules! iotest ( + { fn $name:ident() $b:block $($a:attr)* } => ( + mod $name { + #[allow(unused_imports)]; + + use std::io::timer; + use std::libc; + use std::str; + use std::io::process::{Process, ProcessOutput}; + use native; + use super::*; + + fn f() $b + + $($a)* #[test] fn green() { f() } + $($a)* #[test] fn native() { + use native; + let (tx, rx) = channel(); + native::task::spawn(proc() { tx.send(f()) }); + rx.recv(); + } + } + ) +) + +#[cfg(test)] #[start] +fn start(argc: int, argv: **u8) -> int { + green::start(argc, argv, __test::main) +} + +iotest!(fn test_destroy_once() { #[cfg(not(target_os="android"))] static mut PROG: &'static str = "echo"; @@ -30,10 +61,9 @@ fn test_destroy_once() { let mut p = unsafe {Process::new(PROG, []).unwrap()}; p.signal_exit().unwrap(); // this shouldn't crash (and nor should the destructor) -} +}) -#[test] -fn test_destroy_twice() { +iotest!(fn test_destroy_twice() { #[cfg(not(target_os="android"))] static mut PROG: &'static str = "echo"; #[cfg(target_os="android")] @@ -45,56 +75,27 @@ fn test_destroy_twice() { }; p.signal_exit().unwrap(); // this shouldnt crash... p.signal_exit().unwrap(); // ...and nor should this (and nor should the destructor) -} +}) -fn test_destroy_actually_kills(force: bool) { +pub fn test_destroy_actually_kills(force: bool) { + use std::io::process::{Process, ProcessOutput, ExitStatus, ExitSignal}; + use std::io::timer; + use std::libc; + use std::str; #[cfg(unix,not(target_os="android"))] - static mut BLOCK_COMMAND: &'static str = "cat"; + static BLOCK_COMMAND: &'static str = "cat"; #[cfg(unix,target_os="android")] - static mut BLOCK_COMMAND: &'static str = "/system/bin/cat"; + static BLOCK_COMMAND: &'static str = "/system/bin/cat"; #[cfg(windows)] - static mut BLOCK_COMMAND: &'static str = "cmd"; - - #[cfg(unix,not(target_os="android"))] - fn process_exists(pid: libc::pid_t) -> bool { - let ProcessOutput {output, ..} = Process::output("ps", [~"-p", pid.to_str()]) - .unwrap(); - str::from_utf8_owned(output).unwrap().contains(pid.to_str()) - } - - #[cfg(unix,target_os="android")] - fn process_exists(pid: libc::pid_t) -> bool { - let ProcessOutput {output, ..} = Process::output("/system/bin/ps", [pid.to_str()]) - .unwrap(); - str::from_utf8_owned(output).unwrap().contains(~"root") - } - - #[cfg(windows)] - fn process_exists(pid: libc::pid_t) -> bool { - use std::libc::types::os::arch::extra::DWORD; - use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess}; - use std::libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE }; - - unsafe { - let process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD); - if process.is_null() { - return false; - } - // process will be non-null if the process is alive, or if it died recently - let mut status = 0; - GetExitCodeProcess(process, &mut status); - CloseHandle(process); - return status == STILL_ACTIVE; - } - } + static BLOCK_COMMAND: &'static str = "cmd"; // this process will stay alive indefinitely trying to read from stdin - let mut p = unsafe {Process::new(BLOCK_COMMAND, []).unwrap()}; + let mut p = Process::new(BLOCK_COMMAND, []).unwrap(); - assert!(process_exists(p.id())); + assert!(p.signal(0).is_ok()); if force { p.signal_kill().unwrap(); @@ -102,18 +103,26 @@ fn test_destroy_actually_kills(force: bool) { p.signal_exit().unwrap(); } - if process_exists(p.id()) { - timer::sleep(500); - assert!(!process_exists(p.id())); + // Don't let this test time out, this should be quick + let (tx, rx1) = channel(); + let mut t = timer::Timer::new().unwrap(); + let rx2 = t.oneshot(1000); + spawn(proc() { + select! { + () = rx2.recv() => unsafe { libc::exit(1) }, + () = rx1.recv() => {} + } + }); + match p.wait() { + ExitStatus(..) => fail!("expected a signal"), + ExitSignal(..) => tx.send(()), } } -#[test] -fn test_unforced_destroy_actually_kills() { +iotest!(fn test_unforced_destroy_actually_kills() { test_destroy_actually_kills(false); -} +}) -#[test] -fn test_forced_destroy_actually_kills() { +iotest!(fn test_forced_destroy_actually_kills() { test_destroy_actually_kills(true); -} +}) diff --git a/src/test/run-pass/native-print-no-runtime.rs b/src/test/run-pass/native-print-no-runtime.rs index 67de65cea9fe2..150435959e42c 100644 --- a/src/test/run-pass/native-print-no-runtime.rs +++ b/src/test/run-pass/native-print-no-runtime.rs @@ -10,8 +10,6 @@ // ignore-fast -#[no_uv]; - #[start] pub fn main(_: int, _: **u8) -> int { println!("hello"); diff --git a/src/test/run-pass/process-detach.rs b/src/test/run-pass/process-detach.rs index ffb446d1b3384..319c268201318 100644 --- a/src/test/run-pass/process-detach.rs +++ b/src/test/run-pass/process-detach.rs @@ -20,10 +20,16 @@ // Note that the first thing we do is put ourselves in our own process group so // we don't interfere with other running tests. +extern crate green; +extern crate rustuv; + use std::libc; use std::io::process; use std::io::signal::{Listener, Interrupt}; +#[start] +fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) } + fn main() { unsafe { libc::setsid(); }