(index<- )        ./libstd/io/pipe.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
  1  // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
  2  // file at the top-level directory of this distribution and at
  3  // http://rust-lang.org/COPYRIGHT.
  4  //
  5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8  // option. This file may not be copied, modified, or distributed
  9  // except according to those terms.
 10  
 11  //! Synchronous, in-memory pipes.
 12  //!
 13  //! Currently these aren't particularly useful, there only exists bindings
 14  //! enough so that pipes can be created to child processes.
 15  
 16  #![allow(missing_doc)]
 17  
 18  use prelude::*;
 19  use io::IoResult;
 20  use libc;
 21  use owned::Box;
 22  use rt::rtio::{RtioPipe, LocalIo};
 23  
 24  /// A synchronous, in-memory pipe.
 25  pub struct PipeStream {
 26      /// The internal, opaque runtime pipe object.
 27      obj: Box<RtioPipe:Send>,
 28  }
 29  
 30  impl PipeStream {
 31      /// Consumes a file descriptor to return a pipe stream that will have
 32      /// synchronous, but non-blocking reads/writes. This is useful if the file
 33      /// descriptor is acquired via means other than the standard methods.
 34      ///
 35      /// This operation consumes ownership of the file descriptor and it will be
 36      /// closed once the object is deallocated.
 37      ///
 38      /// # Example
 39      ///
 40      /// ```rust
 41      /// # #![allow(unused_must_use)]
 42      /// extern crate libc;
 43      ///
 44      /// use std::io::pipe::PipeStream;
 45      ///
 46      /// fn main() {
 47      ///     let mut pipe = PipeStream::open(libc::STDERR_FILENO);
 48      ///     pipe.write(bytes!("Hello, stderr!"));
 49      /// }
 50      /// ```
 51      pub fn open(fdlibc::c_int) -> IoResult<PipeStream> {
 52          LocalIo::maybe_raise(|io| {
 53              io.pipe_open(fd).map(|obj| PipeStream { obj: obj })
 54          })
 55      }
 56  
 57      #[doc(hidden)]
 58      pub fn new(innerBox<RtioPipe:Send>) -> PipeStream {
 59          PipeStream { obj: inner }
 60      }
 61  }
 62  
 63  impl Clone for PipeStream {
 64      fn clone(&self) -> PipeStream {
 65          PipeStream { obj: self.obj.clone() }
 66      }
 67  }
 68  
 69  impl Reader for PipeStream {
 70      fn read(&mut self, buf&mut [u8]) -> IoResult<uint> { self.obj.read(buf) }
 71  }
 72  
 73  impl Writer for PipeStream {
 74      fn write(&mut self, buf&[u8]) -> IoResult<()> { self.obj.write(buf) }
 75  }
 76  
 77  #[cfg(test)]
 78  mod test {
 79      iotest!(fn partial_read() {
 80          use os;
 81          use io::pipe::PipeStream;
 82  
 83          let os::Pipe { input, out } = os::pipe();
 84          let out = PipeStream::open(out);
 85          let mut input = PipeStream::open(input);
 86          let (tx, rx) = channel();
 87          spawn(proc() {
 88              let mut out = out;
 89              out.write([10]).unwrap();
 90              rx.recv(); // don't close the pipe until the other read has finished
 91          });
 92  
 93          let mut buf = [0, ..10];
 94          input.read(buf).unwrap();
 95          tx.send(());
 96      })
 97  }