about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-10-22 08:41:05 -0700
committerAlex Crichton <alex@alexcrichton.com>2013-10-24 14:22:35 -0700
commit816e46dd633cf4cc5741dde6ce3bffd4a9ba67a7 (patch)
tree91be9afd56dcda81b3ed6f09e43f9fa4d12290cc
parent262b958a4bedf419335069c95f054a22da48a88a (diff)
Fixing some tests, adding some pipes
This adds constructors to pipe streams in the new runtime to take ownership of
file descriptors, and also fixes a few tests relating to the std::run changes
(new errors are raised on io_error and one test is xfail'd).
-rw-r--r--src/libstd/rt/io/pipe.rs34
-rw-r--r--src/libstd/run.rs9
-rw-r--r--src/test/run-pass/core-run-destroy.rs5
3 files changed, 43 insertions, 5 deletions
diff --git a/src/libstd/rt/io/pipe.rs b/src/libstd/rt/io/pipe.rs
index 979a1dfc65e..ec9a4a0101f 100644
--- a/src/libstd/rt/io/pipe.rs
+++ b/src/libstd/rt/io/pipe.rs
@@ -16,13 +16,45 @@
 use prelude::*;
 use super::{Reader, Writer};
 use rt::io::{io_error, EndOfFile};
-use rt::rtio::RtioPipe;
+use rt::io::native::file;
+use rt::rtio::{RtioPipe, with_local_io};
 
 pub struct PipeStream {
     priv obj: ~RtioPipe,
 }
 
 impl PipeStream {
+    /// Consumes a file descriptor to return a pipe stream that will have
+    /// synchronous, but non-blocking reads/writes. This is useful if the file
+    /// descriptor is acquired via means other than the standard methods.
+    ///
+    /// This operation consumes ownership of the file descriptor and it will be
+    /// closed once the object is deallocated.
+    ///
+    /// # Example
+    ///
+    ///     use std::libc;
+    ///     use std::rt::io::pipe;
+    ///
+    ///     let mut pipe = PipeStream::open(libc::STDERR_FILENO);
+    ///     pipe.write(bytes!("Hello, stderr!"));
+    ///
+    /// # Failure
+    ///
+    /// If the pipe cannot be created, an error will be raised on the
+    /// `io_error` condition.
+    pub fn open(fd: file::fd_t) -> Option<PipeStream> {
+        do with_local_io |io| {
+            match io.pipe_open(fd) {
+                Ok(obj) => Some(PipeStream { obj: obj }),
+                Err(e) => {
+                    io_error::cond.raise(e);
+                    None
+                }
+            }
+        }
+    }
+
     pub fn new(inner: ~RtioPipe) -> PipeStream {
         PipeStream { obj: inner }
     }
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index 40b509c4bc8..650ef491a3b 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -322,6 +322,7 @@ mod tests {
     use path::Path;
     use run;
     use str;
+    use task::spawn;
     use unstable::running_on_valgrind;
     use rt::io::native::file;
     use rt::io::{Writer, Reader};
@@ -394,6 +395,7 @@ mod tests {
     }
 
     #[test]
+    #[ignore] // FIXME(#10016) cat never sees stdin close
     fn test_pipes() {
 
         let pipe_in = os::pipe();
@@ -412,13 +414,14 @@ mod tests {
         os::close(pipe_out.out);
         os::close(pipe_err.out);
 
-        let expected = ~"test";
-        writeclose(pipe_in.out, expected);
+        do spawn {
+            writeclose(pipe_in.out, ~"test");
+        }
         let actual = readclose(pipe_out.input);
         readclose(pipe_err.input);
         proc.finish();
 
-        assert_eq!(expected, actual);
+        assert_eq!(~"test", actual);
     }
 
     fn writeclose(fd: c_int, s: &str) {
diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs
index 0e0e52c6273..4ff184b4483 100644
--- a/src/test/run-pass/core-run-destroy.rs
+++ b/src/test/run-pass/core-run-destroy.rs
@@ -18,6 +18,7 @@
 use std::libc;
 use std::run;
 use std::str;
+use std::rt::io;
 
 #[test]
 fn test_destroy_once() {
@@ -29,7 +30,9 @@ fn test_destroy_once() {
 fn test_destroy_twice() {
     let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
     p.destroy(); // this shouldnt crash...
-    p.destroy(); // ...and nor should this (and nor should the destructor)
+    do io::io_error::cond.trap(|_| {}).inside {
+        p.destroy(); // ...and nor should this (and nor should the destructor)
+    }
 }
 
 fn test_destroy_actually_kills(force: bool) {