From 86a321b65dcc5253f61202b2fdaac41f275344ce Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 7 Nov 2013 20:13:25 -0800 Subject: [PATCH] Another round of test fixes from previous commits --- mk/rt.mk | 2 +- src/librustuv/file.rs | 41 +++++++------- src/librustuv/idle.rs | 9 +++ src/librustuv/lib.rs | 22 +++++++- src/librustuv/net.rs | 50 ++++++++++++++++ src/librustuv/pipe.rs | 88 +++++++++++++++++++++++++++++ src/librustuv/process.rs | 23 +++----- src/librustuv/timer.rs | 78 ++++++++++++++++++++++++- src/librustuv/uvll.rs | 4 +- src/libstd/rt/io/mod.rs | 6 +- src/libstd/rt/io/native/file.rs | 16 ++++-- src/libstd/rt/io/native/process.rs | 6 +- src/libstd/rt/io/native/stdio.rs | 8 +-- src/libstd/rt/io/timer.rs | 6 +- src/libstd/rt/macros.rs | 5 +- src/libstd/run.rs | 4 +- src/rt/rust_uv.cpp | 6 +- src/test/run-pass/closure-reform.rs | 3 +- src/test/run-pass/rtio-processes.rs | 10 ++-- 19 files changed, 312 insertions(+), 75 deletions(-) diff --git a/mk/rt.mk b/mk/rt.mk index 55187fad49d..39679cbed69 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -218,7 +218,7 @@ $$(LIBUV_MAKEFILE_$(1)): $$(LIBUV_DEPS) ifdef CFG_WINDOWSY_$(1) $$(LIBUV_LIB_$(1)): $$(LIBUV_DEPS) $$(Q)$$(MAKE) -C $$(S)src/libuv -f Makefile.mingw \ - CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \ + CC="$$(CC) $$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \ AR="$$(AR_$(1))" \ V=$$(VERBOSE) $$(Q)cp $$(S)src/libuv/libuv.a $$@ diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs index bdb1429f5b6..a5848194d05 100644 --- a/src/librustuv/file.rs +++ b/src/librustuv/file.rs @@ -12,7 +12,7 @@ use std::c_str::CString; use std::c_str; use std::cast::transmute; use std::cast; -use std::libc::{c_int, c_char, c_void, c_uint}; +use std::libc::{c_int, c_char, c_void, size_t}; use std::libc; use std::rt::BlockedTask; use std::rt::io::{FileStat, IoError}; @@ -20,6 +20,7 @@ use std::rt::io; use std::rt::local::Local; use std::rt::rtio; use std::rt::sched::{Scheduler, SchedHandle}; +use std::task; use std::vec; use super::{Loop, UvError, uv_error_to_io_error, wait_until_woken_after}; @@ -79,7 +80,7 @@ impl FsRequest { execute_nop(|req, cb| unsafe { uvll::uv_fs_write(loop_.handle, req, fd, vec::raw::to_ptr(buf) as *c_void, - buf.len() as c_uint, offset, cb) + buf.len() as size_t, offset, cb) }) } @@ -89,7 +90,7 @@ impl FsRequest { do execute(|req, cb| unsafe { uvll::uv_fs_read(loop_.handle, req, fd, vec::raw::to_ptr(buf) as *c_void, - buf.len() as c_uint, offset, cb) + buf.len() as size_t, offset, cb) }).map |req| { req.get_result() as int } @@ -297,24 +298,26 @@ impl Drop for FsRequest { fn execute(f: &fn(*uvll::uv_fs_t, uvll::uv_fs_cb) -> c_int) -> Result { - let mut req = FsRequest { - fired: false, - req: unsafe { uvll::malloc_req(uvll::UV_FS) } - }; - return match f(req.req, fs_cb) { - 0 => { - req.fired = true; - let mut slot = None; - do wait_until_woken_after(&mut slot) { - unsafe { uvll::set_data_for_req(req.req, &slot) } + return do task::unkillable { + let mut req = FsRequest { + fired: false, + req: unsafe { uvll::malloc_req(uvll::UV_FS) } + }; + match f(req.req, fs_cb) { + 0 => { + req.fired = true; + let mut slot = None; + do wait_until_woken_after(&mut slot) { + unsafe { uvll::set_data_for_req(req.req, &slot) } + } + match req.get_result() { + n if n < 0 => Err(UvError(n)), + _ => Ok(req), + } } - match req.get_result() { - n if n < 0 => Err(UvError(n)), - _ => Ok(req), - } - } - n => Err(UvError(n)) + n => Err(UvError(n)) + } }; extern fn fs_cb(req: *uvll::uv_fs_t) { diff --git a/src/librustuv/idle.rs b/src/librustuv/idle.rs index 83fc53dce1c..80481498881 100644 --- a/src/librustuv/idle.rs +++ b/src/librustuv/idle.rs @@ -126,6 +126,15 @@ mod test { tube.recv(); } + #[test] #[should_fail] + fn smoke_fail() { + let tube = Tube::new(); + let cb = ~MyCallback(tube.clone(), 1); + let mut idle = IdleWatcher::new(local_loop(), cb as ~Callback); + idle.resume(); + fail!(); + } + #[test] fn fun_combinations_of_methods() { let mut tube = Tube::new(); diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index 7c84ccb8f2c..edb1953b9b1 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -154,6 +154,26 @@ pub trait UvHandle { } } +pub struct ForbidSwitch { + msg: &'static str, + sched: uint, +} + +impl ForbidSwitch { + fn new(s: &'static str) -> ForbidSwitch { + ForbidSwitch { + msg: s, sched: Local::borrow(|s: &mut Scheduler| s.sched_id()) + } + } +} + +impl Drop for ForbidSwitch { + fn drop(&mut self) { + assert!(self.sched == Local::borrow(|s: &mut Scheduler| s.sched_id()), + "didnt want a scheduler switch: {}", self.msg); + } +} + pub struct ForbidUnwind { msg: &'static str, failing_before: bool, @@ -170,7 +190,7 @@ impl ForbidUnwind { impl Drop for ForbidUnwind { fn drop(&mut self) { assert!(self.failing_before == task::failing(), - "failing sadface {}", self.msg); + "didnt want an unwind during: {}", self.msg); } } diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs index 10b8f50e387..0fc87e4e4fa 100644 --- a/src/librustuv/net.rs +++ b/src/librustuv/net.rs @@ -1168,6 +1168,56 @@ mod test { } } + #[should_fail] #[test] + fn tcp_listener_fail_cleanup() { + let addr = next_test_ip4(); + let w = TcpListener::bind(local_loop(), addr).unwrap(); + let _w = w.listen().unwrap(); + fail!(); + } + + #[should_fail] #[test] + fn tcp_stream_fail_cleanup() { + let (port, chan) = oneshot(); + let chan = Cell::new(chan); + let addr = next_test_ip4(); + + do task::spawn_unlinked { // please no linked failure + let w = TcpListener::bind(local_loop(), addr).unwrap(); + let mut w = w.listen().unwrap(); + chan.take().send(()); + w.accept(); + } + port.recv(); + let _w = TcpWatcher::connect(local_loop(), addr).unwrap(); + fail!(); + } + + #[should_fail] #[test] + fn udp_listener_fail_cleanup() { + let addr = next_test_ip4(); + let _w = UdpWatcher::bind(local_loop(), addr).unwrap(); + fail!(); + } + + #[should_fail] #[test] + fn udp_fail_other_task() { + let addr = next_test_ip4(); + let (port, chan) = oneshot(); + let chan = Cell::new(chan); + + // force the handle to be created on a different scheduler, failure in + // the original task will force a homing operation back to this + // scheduler. + do task::spawn_sched(task::SingleThreaded) { + let w = UdpWatcher::bind(local_loop(), addr).unwrap(); + chan.take().send(w); + } + + let _w = port.recv(); + fail!(); + } + #[should_fail] #[test] #[ignore(reason = "linked failure")] diff --git a/src/librustuv/pipe.rs b/src/librustuv/pipe.rs index 89a86a2ff7d..1b0f352dc4d 100644 --- a/src/librustuv/pipe.rs +++ b/src/librustuv/pipe.rs @@ -238,3 +238,91 @@ impl RtioUnixAcceptor for PipeAcceptor { impl HomingIO for PipeAcceptor { fn home<'r>(&'r mut self) -> &'r mut SchedHandle { self.listener.home() } } + +#[cfg(test)] +mod tests { + use std::cell::Cell; + use std::comm::oneshot; + use std::rt::rtio::{RtioUnixListener, RtioUnixAcceptor, RtioPipe}; + use std::rt::test::next_test_unix; + use std::task; + + use super::*; + use super::super::local_loop; + + #[test] + fn connect_err() { + match PipeWatcher::connect(local_loop(), &"path/to/nowhere".to_c_str()) { + Ok(*) => fail!(), + Err(*) => {} + } + } + + #[test] + fn bind_err() { + match PipeListener::bind(local_loop(), &"path/to/nowhere".to_c_str()) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.name(), ~"EACCES"), + } + } + + #[test] + fn bind() { + let p = next_test_unix().to_c_str(); + match PipeListener::bind(local_loop(), &p) { + Ok(*) => {} + Err(*) => fail!(), + } + } + + #[test] #[should_fail] + fn bind_fail() { + let p = next_test_unix().to_c_str(); + let _w = PipeListener::bind(local_loop(), &p).unwrap(); + fail!(); + } + + #[test] + fn connect() { + let path = next_test_unix(); + let path2 = path.clone(); + let (port, chan) = oneshot(); + let chan = Cell::new(chan); + + do spawn { + let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap(); + let mut p = p.listen().unwrap(); + chan.take().send(()); + let mut client = p.accept().unwrap(); + let mut buf = [0]; + assert!(client.read(buf).unwrap() == 1); + assert_eq!(buf[0], 1); + assert!(client.write([2]).is_ok()); + } + port.recv(); + let mut c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap(); + assert!(c.write([1]).is_ok()); + let mut buf = [0]; + assert!(c.read(buf).unwrap() == 1); + assert_eq!(buf[0], 2); + } + + #[test] #[should_fail] + fn connect_fail() { + let path = next_test_unix(); + let path2 = path.clone(); + let (port, chan) = oneshot(); + let chan = Cell::new(chan); + + do task::spawn_unlinked { // plz no linked failure + let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap(); + let mut p = p.listen().unwrap(); + chan.take().send(()); + p.accept(); + } + port.recv(); + let _c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap(); + fail!() + + } +} diff --git a/src/librustuv/process.rs b/src/librustuv/process.rs index d0b0d6429b8..840ae814f35 100644 --- a/src/librustuv/process.rs +++ b/src/librustuv/process.rs @@ -77,23 +77,18 @@ impl Process { }; let handle = UvHandle::alloc(None::, uvll::UV_PROCESS); + let process = ~Process { + handle: handle, + home: get_handle_to_current_scheduler!(), + to_wake: None, + exit_status: None, + term_signal: None, + }; match unsafe { uvll::uv_spawn(loop_.handle, handle, &options) } { - 0 => { - let process = ~Process { - handle: handle, - home: get_handle_to_current_scheduler!(), - to_wake: None, - exit_status: None, - term_signal: None, - }; - Ok(process.install()) - } - err => { - unsafe { uvll::free_handle(handle) } - Err(UvError(err)) - } + 0 => Ok(process.install()), + err => Err(UvError(err)), } } }; diff --git a/src/librustuv/timer.rs b/src/librustuv/timer.rs index 96cf024639f..664875dd199 100644 --- a/src/librustuv/timer.rs +++ b/src/librustuv/timer.rs @@ -16,7 +16,7 @@ use std::rt::rtio::RtioTimer; use std::rt::sched::{Scheduler, SchedHandle}; use uvll; -use super::{Loop, UvHandle, ForbidUnwind}; +use super::{Loop, UvHandle, ForbidUnwind, ForbidSwitch}; use uvio::HomingIO; pub struct TimerWatcher { @@ -100,7 +100,9 @@ impl RtioTimer for TimerWatcher { } } -extern fn timer_cb(handle: *uvll::uv_timer_t, _status: c_int) { +extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) { + let _f = ForbidSwitch::new("timer callback can't switch"); + assert_eq!(status, 0); let timer: &mut TimerWatcher = unsafe { UvHandle::from_uv_handle(&handle) }; match timer.action.take_unwrap() { @@ -168,4 +170,76 @@ mod test { timer.sleep(1); timer.sleep(1); } + + #[test] #[should_fail] + fn oneshot_fail() { + let mut timer = TimerWatcher::new(local_loop()); + let _port = timer.oneshot(1); + fail!(); + } + + #[test] #[should_fail] + fn period_fail() { + let mut timer = TimerWatcher::new(local_loop()); + let _port = timer.period(1); + fail!(); + } + + #[test] #[should_fail] + fn normal_fail() { + let _timer = TimerWatcher::new(local_loop()); + fail!(); + } + + #[test] + fn closing_channel_during_drop_doesnt_kill_everything() { + // see issue #10375 + let mut timer = TimerWatcher::new(local_loop()); + let timer_port = Cell::new(timer.period(1000)); + + do spawn { + timer_port.take().try_recv(); + } + + // when we drop the TimerWatcher we're going to destroy the channel, + // which must wake up the task on the other end + } + + #[test] + fn sender_goes_away_oneshot() { + let port = { + let mut timer = TimerWatcher::new(local_loop()); + timer.oneshot(1000) + }; + assert_eq!(port.try_recv(), None); + } + + #[test] + fn sender_goes_away_period() { + let port = { + let mut timer = TimerWatcher::new(local_loop()); + timer.period(1000) + }; + assert_eq!(port.try_recv(), None); + } + + #[test] + fn receiver_goes_away_oneshot() { + let mut timer1 = TimerWatcher::new(local_loop()); + timer1.oneshot(1); + let mut timer2 = TimerWatcher::new(local_loop()); + // while sleeping, the prevous timer should fire and not have its + // callback do something terrible. + timer2.sleep(2); + } + + #[test] + fn receiver_goes_away_period() { + let mut timer1 = TimerWatcher::new(local_loop()); + timer1.period(1); + let mut timer2 = TimerWatcher::new(local_loop()); + // while sleeping, the prevous timer should fire and not have its + // callback do something terrible. + timer2.sleep(2); + } } diff --git a/src/librustuv/uvll.rs b/src/librustuv/uvll.rs index 4183ce4309e..5f68ac5e71d 100644 --- a/src/librustuv/uvll.rs +++ b/src/librustuv/uvll.rs @@ -676,9 +676,9 @@ externfn!(fn uv_fs_open(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, externfn!(fn uv_fs_unlink(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, cb: uv_fs_cb) -> c_int) externfn!(fn uv_fs_write(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void, - len: c_uint, offset: i64, cb: uv_fs_cb) -> c_int) + len: size_t, offset: i64, cb: uv_fs_cb) -> c_int) externfn!(fn uv_fs_read(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void, - len: c_uint, offset: i64, cb: uv_fs_cb) -> c_int) + len: size_t, offset: i64, cb: uv_fs_cb) -> c_int) externfn!(fn uv_fs_close(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, cb: uv_fs_cb) -> c_int) externfn!(fn uv_fs_stat(l: *uv_loop_t, req: *uv_fs_t, path: *c_char, diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs index e8ab4670233..ce9504a5b43 100644 --- a/src/libstd/rt/io/mod.rs +++ b/src/libstd/rt/io/mod.rs @@ -423,7 +423,11 @@ pub fn ignore_io_error(cb: &fn() -> T) -> T { /// closure if no error occurred. pub fn result(cb: &fn() -> T) -> Result { let mut err = None; - let ret = io_error::cond.trap(|e| err = Some(e)).inside(cb); + let ret = io_error::cond.trap(|e| { + if err.is_none() { + err = Some(e); + } + }).inside(cb); match err { Some(e) => Err(e), None => Ok(ret), diff --git a/src/libstd/rt/io/native/file.rs b/src/libstd/rt/io/native/file.rs index 35057f475cf..6d4f29182dd 100644 --- a/src/libstd/rt/io/native/file.rs +++ b/src/libstd/rt/io/native/file.rs @@ -80,18 +80,20 @@ pub type fd_t = libc::c_int; pub struct FileDesc { priv fd: fd_t, + priv close_on_drop: bool, } impl FileDesc { /// Create a `FileDesc` from an open C file descriptor. /// /// The `FileDesc` will take ownership of the specified file descriptor and - /// close it upon destruction. + /// close it upon destruction if the `close_on_drop` flag is true, otherwise + /// it will not close the file descriptor when this `FileDesc` is dropped. /// /// Note that all I/O operations done on this object will be *blocking*, but /// they do not require the runtime to be active. - pub fn new(fd: fd_t) -> FileDesc { - FileDesc { fd: fd } + pub fn new(fd: fd_t, close_on_drop: bool) -> FileDesc { + FileDesc { fd: fd, close_on_drop: close_on_drop } } } @@ -137,7 +139,9 @@ impl Writer for FileDesc { impl Drop for FileDesc { #[fixed_stack_segment] #[inline(never)] fn drop(&mut self) { - unsafe { libc::close(self.fd); } + if self.close_on_drop { + unsafe { libc::close(self.fd); } + } } } @@ -245,8 +249,8 @@ mod tests { // opening or closing files. unsafe { let os::Pipe { input, out } = os::pipe(); - let mut reader = FileDesc::new(input); - let mut writer = FileDesc::new(out); + let mut reader = FileDesc::new(input, true); + let mut writer = FileDesc::new(out, true); writer.write(bytes!("test")); let mut buf = [0u8, ..4]; diff --git a/src/libstd/rt/io/native/process.rs b/src/libstd/rt/io/native/process.rs index 0fa454b94d0..f5c39de1bf4 100644 --- a/src/libstd/rt/io/native/process.rs +++ b/src/libstd/rt/io/native/process.rs @@ -105,9 +105,9 @@ impl Process { Process { pid: res.pid, handle: res.handle, - input: in_pipe.map(|pipe| file::FileDesc::new(pipe.out)), - output: out_pipe.map(|pipe| file::FileDesc::new(pipe.input)), - error: err_pipe.map(|pipe| file::FileDesc::new(pipe.input)), + input: in_pipe.map(|pipe| file::FileDesc::new(pipe.out, true)), + output: out_pipe.map(|pipe| file::FileDesc::new(pipe.input, true)), + error: err_pipe.map(|pipe| file::FileDesc::new(pipe.input, true)), exit_code: None, } } diff --git a/src/libstd/rt/io/native/stdio.rs b/src/libstd/rt/io/native/stdio.rs index 5661725d77b..ddfbb9a8f8c 100644 --- a/src/libstd/rt/io/native/stdio.rs +++ b/src/libstd/rt/io/native/stdio.rs @@ -36,10 +36,8 @@ pub struct StdIn { impl StdIn { /// Duplicates the stdin file descriptor, returning an io::Reader - #[fixed_stack_segment] #[inline(never)] pub fn new() -> StdIn { - let fd = unsafe { libc::dup(libc::STDIN_FILENO) }; - StdIn { fd: file::FileDesc::new(fd) } + StdIn { fd: file::FileDesc::new(libc::STDIN_FILENO, false) } } } @@ -54,10 +52,8 @@ pub struct StdOut { impl StdOut { /// Duplicates the specified file descriptor, returning an io::Writer - #[fixed_stack_segment] #[inline(never)] pub fn new(fd: file::fd_t) -> StdOut { - let fd = unsafe { libc::dup(fd) }; - StdOut { fd: file::FileDesc::new(fd) } + StdOut { fd: file::FileDesc::new(fd, false) } } } diff --git a/src/libstd/rt/io/timer.rs b/src/libstd/rt/io/timer.rs index 36092dfbe34..fed6b9daa64 100644 --- a/src/libstd/rt/io/timer.rs +++ b/src/libstd/rt/io/timer.rs @@ -160,11 +160,7 @@ mod test { let port = timer.oneshot(100000000000); timer.sleep(1); // this should invalidate the port - let port = Cell::new(port); - let ret = do task::try { - port.take().recv(); - }; - assert!(ret.is_err()); + assert_eq!(port.try_recv(), None); } } diff --git a/src/libstd/rt/macros.rs b/src/libstd/rt/macros.rs index 2c89bfd8c76..3ef57710344 100644 --- a/src/libstd/rt/macros.rs +++ b/src/libstd/rt/macros.rs @@ -42,8 +42,7 @@ macro_rules! rtassert ( macro_rules! rtabort ( - ($msg:expr $($arg:tt)*) => ( { - ::rt::util::abort(format!(concat!(file!(), ":", line!(), " ", $msg) - $($arg)*)); + ($($arg:tt)*) => ( { + ::rt::util::abort(format!($($arg)*)); } ) ) diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 74f4ed3d55e..fe23944397d 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -436,13 +436,13 @@ mod tests { } fn writeclose(fd: c_int, s: &str) { - let mut writer = file::FileDesc::new(fd); + let mut writer = file::FileDesc::new(fd, true); writer.write(s.as_bytes()); } fn readclose(fd: c_int) -> ~str { let mut res = ~[]; - let mut reader = file::FileDesc::new(fd); + let mut reader = file::FileDesc::new(fd, true); let mut buf = [0, ..1024]; loop { match reader.read(buf) { diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index 280b016af10..f3be486a25a 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -93,8 +93,7 @@ rust_sockaddr_size() { extern "C" struct sockaddr* rust_malloc_ip4_addr(char *name, int port) { - struct sockaddr_in *addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in)); - memset(addr, 0, sizeof(struct sockaddr_in)); + struct sockaddr_in *addr = (struct sockaddr_in*) calloc(1, rust_sockaddr_size()); assert(addr != NULL); addr->sin_port = htons(port); assert(uv_inet_pton(AF_INET, name, &addr->sin_addr) == 0); @@ -104,8 +103,7 @@ rust_malloc_ip4_addr(char *name, int port) { extern "C" struct sockaddr* rust_malloc_ip6_addr(char *name, int port) { - struct sockaddr_in6 *addr = (struct sockaddr_in6*) malloc(sizeof(struct sockaddr_in6)); - memset(addr, 0, sizeof(struct sockaddr)); + struct sockaddr_in6 *addr = (struct sockaddr_in6*) calloc(1, rust_sockaddr_size()); assert(addr != NULL); addr->sin6_port = htons(port); assert(uv_inet_pton(AF_INET6, name, &addr->sin6_addr) == 0); diff --git a/src/test/run-pass/closure-reform.rs b/src/test/run-pass/closure-reform.rs index 18ca64d0f27..629a8072661 100644 --- a/src/test/run-pass/closure-reform.rs +++ b/src/test/run-pass/closure-reform.rs @@ -67,7 +67,8 @@ pub fn main() { call_that(|x, y| *x + *y - z); call_cramped(|| 1, || unsafe { - cast::transmute(&100) + static a: uint = 100; + cast::transmute(&a) }); // External functions diff --git a/src/test/run-pass/rtio-processes.rs b/src/test/run-pass/rtio-processes.rs index 14595f83ce5..f45889eeb03 100644 --- a/src/test/run-pass/rtio-processes.rs +++ b/src/test/run-pass/rtio-processes.rs @@ -23,8 +23,8 @@ // // See #9341 +use std::rt::io; use std::rt::io::process::{Process, ProcessConfig, CreatePipe, Ignored}; -use std::rt::io::{Reader, Writer}; use std::str; #[test] @@ -55,10 +55,10 @@ fn smoke_failure() { cwd: None, io: io, }; - let p = Process::new(args); - assert!(p.is_some()); - let mut p = p.unwrap(); - assert!(p.wait() != 0); + match io::result(|| Process::new(args)) { + Ok(*) => fail!(), + Err(*) => {} + } } #[test]