Skip to content

Commit facefa7

Browse files
committed
Implement rt::io::stdio
Additionally, this moves the prelude imports of print/println from std::io to std::rt::io. Closes #6846
1 parent a0d2f71 commit facefa7

File tree

3 files changed

+84
-26
lines changed

3 files changed

+84
-26
lines changed

src/libstd/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub use option::{Option, Some, None};
3939
pub use result::{Result, Ok, Err};
4040

4141
// Reexported functions
42-
pub use io::{print, println};
42+
pub use rt::io::stdio::{print, println};
4343
pub use iter::range;
4444
pub use from_str::from_str;
4545

src/libstd/rt/io/native/file.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ mod tests {
223223
use super::*;
224224

225225
#[test] #[fixed_stack_segment]
226+
#[ignore(cfg(target_os = "freebsd"))] // hmm, maybe pipes have a tiny buffer
226227
fn test_file_desc() {
227228
// Run this test with some pipes so we don't have to mess around with
228229
// opening or closing files.
@@ -258,7 +259,7 @@ mod tests {
258259
}
259260

260261
#[test] #[fixed_stack_segment]
261-
#[ignore(windows)] // apparently windows doesn't like tmpfile
262+
#[ignore(cfg(windows))] // apparently windows doesn't like tmpfile
262263
fn test_cfile() {
263264
unsafe {
264265
let f = libc::tmpfile();

src/libstd/rt/io/stdio.rs

Lines changed: 81 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,102 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

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};
1317

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+
}
1928

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+
}
2142

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+
}
2353

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());
2861
}
2962

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+
}
3170

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
3474
}
3575

3676
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+
}
3886

39-
fn eof(&mut self) -> bool { fail2!() }
87+
fn eof(&mut self) -> bool { false }
4088
}
4189

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
4693
}
4794

4895
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+
}
50102

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+
}
52109
}

0 commit comments

Comments
 (0)