|
8 | 8 | // option. This file may not be copied, modified, or distributed
|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
11 |
| -use prelude::*; |
12 |
| -use super::{Reader, Writer}; |
| 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}; |
13 | 17 |
|
14 |
| -pub fn stdin() -> StdReader { fail2!() } |
15 |
| - |
16 |
| -pub fn stdout() -> StdWriter { fail2!() } |
17 |
| - |
18 |
| -pub fn stderr() -> StdReader { fail2!() } |
| 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 | +} |
19 | 28 |
|
20 |
| -pub fn print(_s: &str) { fail2!() } |
| 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 | +} |
21 | 42 |
|
22 |
| -pub fn println(_s: &str) { fail2!() } |
| 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 | +} |
23 | 53 |
|
24 |
| -pub enum StdStream { |
25 |
| - StdIn, |
26 |
| - StdOut, |
27 |
| - StdErr |
| 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()); |
28 | 61 | }
|
29 | 62 |
|
30 |
| -pub struct StdReader; |
| 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 | +} |
31 | 70 |
|
32 |
| -impl StdReader { |
33 |
| - pub fn new(_stream: StdStream) -> StdReader { fail2!() } |
| 71 | +/// Representation of a reader of a standard input stream |
| 72 | +pub struct StdReader { |
| 73 | + priv inner: ~RtioFileStream |
34 | 74 | }
|
35 | 75 |
|
36 | 76 | impl Reader for StdReader {
|
37 |
| - fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail2!() } |
| 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 | + } |
38 | 86 |
|
39 |
| - fn eof(&mut self) -> bool { fail2!() } |
| 87 | + fn eof(&mut self) -> bool { false } |
40 | 88 | }
|
41 | 89 |
|
42 |
| -pub struct StdWriter; |
43 |
| - |
44 |
| -impl StdWriter { |
45 |
| - pub fn new(_stream: StdStream) -> StdWriter { fail2!() } |
| 90 | +/// Representation of a writer to a standard output stream |
| 91 | +pub struct StdWriter { |
| 92 | + priv inner: ~RtioFileStream |
46 | 93 | }
|
47 | 94 |
|
48 | 95 | impl Writer for StdWriter {
|
49 |
| - fn write(&mut self, _buf: &[u8]) { fail2!() } |
| 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 | + } |
50 | 102 |
|
51 |
| - fn flush(&mut self) { fail2!() } |
| 103 | + fn flush(&mut self) { |
| 104 | + match self.inner.flush() { |
| 105 | + Ok(()) => {} |
| 106 | + Err(e) => io_error::cond.raise(e) |
| 107 | + } |
| 108 | + } |
52 | 109 | }
|
0 commit comments