(index<- )        ./libstd/rt/io/stdio.rs

   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  use libc;
  12  use option::{Option, Some, None};
  13  use result::{Ok, Err};
  14  use rt::local::Local;
  15  use rt::rtio::{RtioFileStream, IoFactoryObject, IoFactory};
  16  use super::{Reader, Writer, io_error};
  17  
  18  /// Creates a new non-blocking handle to the stdin of the current process.
  19  ///
  20  /// See `stdout()` for notes about this function.
  21  pub fn stdin() -> StdReader {
  22      let stream = unsafe {
  23          let io*mut IoFactoryObject = Local::unsafe_borrow();
  24          (*io).fs_from_raw_fd(libc::STDIN_FILENO, false)
  25      };
  26      StdReader { inner: stream }
  27  }
  28  
  29  /// Creates a new non-blocking handle to the stdout of the current process.
  30  ///
  31  /// Note that this is a fairly expensive operation in that at least one memory
  32  /// allocation is performed. Additionally, this must be called from a runtime
  33  /// task context because the stream returned will be a non-blocking object using
  34  /// the local scheduler to perform the I/O.
  35  pub fn stdout() -> StdWriter {
  36      let stream = unsafe {
  37          let io*mut IoFactoryObject = Local::unsafe_borrow();
  38          (*io).fs_from_raw_fd(libc::STDOUT_FILENO, false)
  39      };
  40      StdWriter { inner: stream }
  41  }
  42  
  43  /// Creates a new non-blocking handle to the stderr of the current process.
  44  ///
  45  /// See `stdout()` for notes about this function.
  46  pub fn stderr() -> StdWriter {
  47      let stream = unsafe {
  48          let io*mut IoFactoryObject = Local::unsafe_borrow();
  49          (*io).fs_from_raw_fd(libc::STDERR_FILENO, false)
  50      };
  51      StdWriter { inner: stream }
  52  }
  53  
  54  /// Prints a string to the stdout of the current process. No newline is emitted
  55  /// after the string is printed.
  56  pub fn print(s&str) {
  57      // XXX: need to see if not caching stdin() is the cause of performance
  58      //      issues, it should be possible to cache a stdout handle in each Task
  59      //      and then re-use that across calls to print/println
  60      stdout().write(s.as_bytes());
  61  }
  62  
  63  /// Prints a string as a line. to the stdout of the current process. A literal
  64  /// `\n` character is printed to the console after the string.
  65  pub fn println(s&str) {
  66      let mut out = stdout();
  67      out.write(s.as_bytes());
  68      out.write(['\n' as u8]);
  69  }
  70  
  71  /// Representation of a reader of a standard input stream
  72  pub struct StdReader {
  73      priv inner: ~RtioFileStream
  74  }
  75  
  76  impl Reader for StdReader {
  77      fn read(&mut self, buf&mut [u8]) -> Option<uint> {
  78          match self.inner.read(buf) {
  79              Ok(amt) => Some(amt as uint),
  80              Err(e) => {
  81                  io_error::cond.raise(e);
  82                  None
  83              }
  84          }
  85      }
  86  
  87      fn eof(&mut self) -> bool { false }
  88  }
  89  
  90  /// Representation of a writer to a standard output stream
  91  pub struct StdWriter {
  92      priv inner: ~RtioFileStream
  93  }
  94  
  95  impl Writer for StdWriter {
  96      fn write(&mut self, buf&[u8]) {
  97          match self.inner.write(buf) {
  98              Ok(()) => {}
  99              Err(e) => io_error::cond.raise(e)
 100          }
 101      }
 102  
 103      fn flush(&mut self) {
 104          match self.inner.flush() {
 105              Ok(()) => {}
 106              Err(e) => io_error::cond.raise(e)
 107          }
 108      }
 109  }