about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/prelude.rs2
-rw-r--r--src/libstd/rt/io/native/file.rs3
-rw-r--r--src/libstd/rt/io/stdio.rs105
3 files changed, 84 insertions, 26 deletions
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 273a01c1811..3da337add94 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -39,7 +39,7 @@ pub use option::{Option, Some, None};
 pub use result::{Result, Ok, Err};
 
 // Reexported functions
-pub use io::{print, println};
+pub use rt::io::stdio::{print, println};
 pub use iter::range;
 pub use from_str::from_str;
 
diff --git a/src/libstd/rt/io/native/file.rs b/src/libstd/rt/io/native/file.rs
index f0dd63a3224..dc8d34d1b11 100644
--- a/src/libstd/rt/io/native/file.rs
+++ b/src/libstd/rt/io/native/file.rs
@@ -223,6 +223,7 @@ mod tests {
     use super::*;
 
     #[test] #[fixed_stack_segment]
+    #[ignore(cfg(target_os = "freebsd"))] // hmm, maybe pipes have a tiny buffer
     fn test_file_desc() {
         // Run this test with some pipes so we don't have to mess around with
         // opening or closing files.
@@ -258,7 +259,7 @@ mod tests {
     }
 
     #[test] #[fixed_stack_segment]
-    #[ignore(windows)] // apparently windows doesn't like tmpfile
+    #[ignore(cfg(windows))] // apparently windows doesn't like tmpfile
     fn test_cfile() {
         unsafe {
             let f = libc::tmpfile();
diff --git a/src/libstd/rt/io/stdio.rs b/src/libstd/rt/io/stdio.rs
index 734a40429a6..e3ca148862f 100644
--- a/src/libstd/rt/io/stdio.rs
+++ b/src/libstd/rt/io/stdio.rs
@@ -8,45 +8,102 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
-use super::{Reader, Writer};
+use libc;
+use option::{Option, Some, None};
+use result::{Ok, Err};
+use rt::local::Local;
+use rt::rtio::{RtioFileStream, IoFactoryObject, IoFactory};
+use super::{Reader, Writer, io_error};
 
-pub fn stdin() -> StdReader { fail2!() }
-
-pub fn stdout() -> StdWriter { fail2!() }
-
-pub fn stderr() -> StdReader { fail2!() }
+/// Creates a new non-blocking handle to the stdin of the current process.
+///
+/// See `stdout()` for notes about this function.
+pub fn stdin() -> StdReader {
+    let stream = unsafe {
+        let io: *mut IoFactoryObject = Local::unsafe_borrow();
+        (*io).fs_from_raw_fd(libc::STDIN_FILENO, false)
+    };
+    StdReader { inner: stream }
+}
 
-pub fn print(_s: &str) { fail2!() }
+/// Creates a new non-blocking handle to the stdout of the current process.
+///
+/// Note that this is a fairly expensive operation in that at least one memory
+/// allocation is performed. Additionally, this must be called from a runtime
+/// task context because the stream returned will be a non-blocking object using
+/// the local scheduler to perform the I/O.
+pub fn stdout() -> StdWriter {
+    let stream = unsafe {
+        let io: *mut IoFactoryObject = Local::unsafe_borrow();
+        (*io).fs_from_raw_fd(libc::STDOUT_FILENO, false)
+    };
+    StdWriter { inner: stream }
+}
 
-pub fn println(_s: &str) { fail2!() }
+/// Creates a new non-blocking handle to the stderr of the current process.
+///
+/// See `stdout()` for notes about this function.
+pub fn stderr() -> StdWriter {
+    let stream = unsafe {
+        let io: *mut IoFactoryObject = Local::unsafe_borrow();
+        (*io).fs_from_raw_fd(libc::STDERR_FILENO, false)
+    };
+    StdWriter { inner: stream }
+}
 
-pub enum StdStream {
-    StdIn,
-    StdOut,
-    StdErr
+/// Prints a string to the stdout of the current process. No newline is emitted
+/// after the string is printed.
+pub fn print(s: &str) {
+    // XXX: need to see if not caching stdin() is the cause of performance
+    //      issues, it should be possible to cache a stdout handle in each Task
+    //      and then re-use that across calls to print/println
+    stdout().write(s.as_bytes());
 }
 
-pub struct StdReader;
+/// Prints a string as a line. to the stdout of the current process. A literal
+/// `\n` character is printed to the console after the string.
+pub fn println(s: &str) {
+    let mut out = stdout();
+    out.write(s.as_bytes());
+    out.write(['\n' as u8]);
+}
 
-impl StdReader {
-    pub fn new(_stream: StdStream) -> StdReader { fail2!() }
+/// Representation of a reader of a standard input stream
+pub struct StdReader {
+    priv inner: ~RtioFileStream
 }
 
 impl Reader for StdReader {
-    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail2!() }
+    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+        match self.inner.read(buf) {
+            Ok(amt) => Some(amt as uint),
+            Err(e) => {
+                io_error::cond.raise(e);
+                None
+            }
+        }
+    }
 
-    fn eof(&mut self) -> bool { fail2!() }
+    fn eof(&mut self) -> bool { false }
 }
 
-pub struct StdWriter;
-
-impl StdWriter {
-    pub fn new(_stream: StdStream) -> StdWriter { fail2!() }
+/// Representation of a writer to a standard output stream
+pub struct StdWriter {
+    priv inner: ~RtioFileStream
 }
 
 impl Writer for StdWriter {
-    fn write(&mut self, _buf: &[u8]) { fail2!() }
+    fn write(&mut self, buf: &[u8]) {
+        match self.inner.write(buf) {
+            Ok(()) => {}
+            Err(e) => io_error::cond.raise(e)
+        }
+    }
 
-    fn flush(&mut self) { fail2!() }
+    fn flush(&mut self) {
+        match self.inner.flush() {
+            Ok(()) => {}
+            Err(e) => io_error::cond.raise(e)
+        }
+    }
 }