Skip to content

Commit cf7ca43

Browse files
committed
---
yaml --- r: 146158 b: refs/heads/try2 c: 35756fb h: refs/heads/master v: v3
1 parent 0215081 commit cf7ca43

File tree

14 files changed

+308
-163
lines changed

14 files changed

+308
-163
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 32b07c6a40bd7e1874244096f413096a6e059a29
8+
refs/heads/try2: 35756fbcf6572d588929fde64fb4027f47e9d0af
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libstd/rt/io/stdio.rs

Lines changed: 88 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use libc;
1313
use option::{Option, Some, None};
1414
use result::{Ok, Err};
1515
use rt::local::Local;
16-
use rt::rtio::{RtioFileStream, IoFactoryObject, IoFactory};
16+
use rt::rtio::{IoFactoryObject, IoFactory, RtioTTYObject, RtioTTY};
1717
use super::{Reader, Writer, io_error};
1818

1919
/// Creates a new non-blocking handle to the stdin of the current process.
@@ -22,8 +22,8 @@ use super::{Reader, Writer, io_error};
2222
pub fn stdin() -> StdReader {
2323
let stream = unsafe {
2424
let io: *mut IoFactoryObject = Local::unsafe_borrow();
25-
(*io).fs_from_raw_fd(libc::STDIN_FILENO, false)
26-
};
25+
(*io).tty_open(libc::STDIN_FILENO, true, false)
26+
}.unwrap();
2727
StdReader { inner: stream }
2828
}
2929

@@ -36,8 +36,8 @@ pub fn stdin() -> StdReader {
3636
pub fn stdout() -> StdWriter {
3737
let stream = unsafe {
3838
let io: *mut IoFactoryObject = Local::unsafe_borrow();
39-
(*io).fs_from_raw_fd(libc::STDOUT_FILENO, false)
40-
};
39+
(*io).tty_open(libc::STDOUT_FILENO, false, false)
40+
}.unwrap();
4141
StdWriter { inner: stream }
4242
}
4343

@@ -47,8 +47,8 @@ pub fn stdout() -> StdWriter {
4747
pub fn stderr() -> StdWriter {
4848
let stream = unsafe {
4949
let io: *mut IoFactoryObject = Local::unsafe_borrow();
50-
(*io).fs_from_raw_fd(libc::STDERR_FILENO, false)
51-
};
50+
(*io).tty_open(libc::STDERR_FILENO, false, false)
51+
}.unwrap();
5252
StdWriter { inner: stream }
5353
}
5454

@@ -87,7 +87,30 @@ pub fn println_args(fmt: &fmt::Arguments) {
8787

8888
/// Representation of a reader of a standard input stream
8989
pub struct StdReader {
90-
priv inner: ~RtioFileStream
90+
priv inner: ~RtioTTYObject
91+
}
92+
93+
impl StdReader {
94+
/// Controls whether this output stream is a "raw stream" or simply a normal
95+
/// stream.
96+
///
97+
/// # Failure
98+
///
99+
/// This function will raise on the `io_error` condition if an error
100+
/// happens.
101+
pub fn set_raw(&mut self, raw: bool) {
102+
match self.inner.set_raw(raw) {
103+
Ok(()) => {},
104+
Err(e) => io_error::cond.raise(e),
105+
}
106+
}
107+
108+
/// Resets the mode of this stream back to its original state.
109+
///
110+
/// # Failure
111+
///
112+
/// This function cannot fail.
113+
pub fn reset_mode(&mut self) { self.inner.reset_mode(); }
91114
}
92115

93116
impl Reader for StdReader {
@@ -106,7 +129,50 @@ impl Reader for StdReader {
106129

107130
/// Representation of a writer to a standard output stream
108131
pub struct StdWriter {
109-
priv inner: ~RtioFileStream
132+
priv inner: ~RtioTTYObject
133+
}
134+
135+
impl StdWriter {
136+
/// Gets the size of this output window, if possible. This is typically used
137+
/// when the writer is attached to something like a terminal, this is used
138+
/// to fetch the dimensions of the terminal.
139+
///
140+
/// If successful, returns Some((width, height)).
141+
///
142+
/// # Failure
143+
///
144+
/// This function will raise on the `io_error` condition if an error
145+
/// happens.
146+
pub fn winsize(&mut self) -> Option<(int, int)> {
147+
match self.inner.get_winsize() {
148+
Ok(p) => Some(p),
149+
Err(e) => {
150+
io_error::cond.raise(e);
151+
None
152+
}
153+
}
154+
}
155+
156+
/// Controls whether this output stream is a "raw stream" or simply a normal
157+
/// stream.
158+
///
159+
/// # Failure
160+
///
161+
/// This function will raise on the `io_error` condition if an error
162+
/// happens.
163+
pub fn set_raw(&mut self, raw: bool) {
164+
match self.inner.set_raw(raw) {
165+
Ok(()) => {},
166+
Err(e) => io_error::cond.raise(e),
167+
}
168+
}
169+
170+
/// Resets the mode of this stream back to its original state.
171+
///
172+
/// # Failure
173+
///
174+
/// This function cannot fail.
175+
pub fn reset_mode(&mut self) { self.inner.reset_mode(); }
110176
}
111177

112178
impl Writer for StdWriter {
@@ -117,10 +183,18 @@ impl Writer for StdWriter {
117183
}
118184
}
119185

120-
fn flush(&mut self) {
121-
match self.inner.flush() {
122-
Ok(()) => {}
123-
Err(e) => io_error::cond.raise(e)
124-
}
186+
fn flush(&mut self) { /* nothing to do */ }
187+
}
188+
189+
#[cfg(test)]
190+
mod tests {
191+
use super::*;
192+
193+
#[test]
194+
fn smoke() {
195+
// Just make sure we can acquire handles
196+
stdin();
197+
stdout();
198+
stderr();
125199
}
126200
}

branches/try2/src/libstd/rt/rtio.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub type RtioPipeObject = uvio::UvPipeStream;
3838
pub type RtioProcessObject = uvio::UvProcess;
3939
pub type RtioUnixListenerObject = uvio::UvUnixListener;
4040
pub type RtioUnixAcceptorObject = uvio::UvUnixAcceptor;
41+
pub type RtioTTYObject = uvio::UvTTY;
4142

4243
pub trait EventLoop {
4344
fn run(&mut self);
@@ -94,6 +95,8 @@ pub trait IoFactory {
9495
Result<~RtioUnixListenerObject, IoError>;
9596
fn unix_connect<P: PathLike>(&mut self, path: &P) ->
9697
Result<~RtioPipeObject, IoError>;
98+
fn tty_open(&mut self, fd: c_int, readable: bool, close_on_drop: bool)
99+
-> Result<~RtioTTYObject, IoError>;
97100
}
98101

99102
pub trait RtioTcpListener : RtioSocket {
@@ -171,3 +174,11 @@ pub trait RtioUnixAcceptor {
171174
fn accept_simultaneously(&mut self) -> Result<(), IoError>;
172175
fn dont_accept_simultaneously(&mut self) -> Result<(), IoError>;
173176
}
177+
178+
pub trait RtioTTY {
179+
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
180+
fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
181+
fn set_raw(&mut self, raw: bool) -> Result<(), IoError>;
182+
fn reset_mode(&mut self);
183+
fn get_winsize(&mut self) -> Result<(int, int), IoError>;
184+
}

branches/try2/src/libstd/rt/uv/async.rs

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

11-
use libc::{c_int, c_void};
11+
use libc::c_int;
1212
use option::Some;
1313
use rt::uv::uvll;
1414
use rt::uv::uvll::UV_ASYNC;
15-
use rt::uv::{Watcher, Loop, NativeHandle, AsyncCallback, NullCallback};
15+
use rt::uv::{Watcher, Loop, NativeHandle, AsyncCallback};
1616
use rt::uv::WatcherInterop;
1717
use rt::uv::status_to_maybe_uv_error;
1818

@@ -47,27 +47,6 @@ impl AsyncWatcher {
4747
uvll::async_send(handle);
4848
}
4949
}
50-
51-
pub fn close(self, cb: NullCallback) {
52-
let mut this = self;
53-
let data = this.get_watcher_data();
54-
assert!(data.close_cb.is_none());
55-
data.close_cb = Some(cb);
56-
57-
unsafe {
58-
uvll::close(self.native_handle(), close_cb);
59-
}
60-
61-
extern fn close_cb(handle: *uvll::uv_stream_t) {
62-
let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle);
63-
{
64-
let data = watcher.get_watcher_data();
65-
data.close_cb.take_unwrap()();
66-
}
67-
watcher.drop_watcher_data();
68-
unsafe { uvll::free_handle(handle as *c_void); }
69-
}
70-
}
7150
}
7251

7352
impl NativeHandle<*uvll::uv_async_t> for AsyncWatcher {

branches/try2/src/libstd/rt/uv/idle.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use libc::c_int;
1212
use option::Some;
1313
use rt::uv::uvll;
14-
use rt::uv::{Watcher, Loop, NativeHandle, IdleCallback, NullCallback};
14+
use rt::uv::{Watcher, Loop, NativeHandle, IdleCallback};
1515
use rt::uv::status_to_maybe_uv_error;
1616

1717
pub struct IdleWatcher(*uvll::uv_idle_t);
@@ -71,29 +71,6 @@ impl IdleWatcher {
7171
assert!(0 == uvll::idle_stop(self.native_handle()));
7272
}
7373
}
74-
75-
pub fn close(self, cb: NullCallback) {
76-
{
77-
let mut this = self;
78-
let data = this.get_watcher_data();
79-
assert!(data.close_cb.is_none());
80-
data.close_cb = Some(cb);
81-
}
82-
83-
unsafe { uvll::close(self.native_handle(), close_cb) };
84-
85-
extern fn close_cb(handle: *uvll::uv_idle_t) {
86-
unsafe {
87-
let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
88-
{
89-
let data = idle_watcher.get_watcher_data();
90-
data.close_cb.take_unwrap()();
91-
}
92-
idle_watcher.drop_watcher_data();
93-
uvll::idle_delete(handle);
94-
}
95-
}
96-
}
9774
}
9875

9976
impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher {

branches/try2/src/libstd/rt/uv/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub mod async;
7575
pub mod addrinfo;
7676
pub mod process;
7777
pub mod pipe;
78+
pub mod tty;
7879

7980
/// XXX: Loop(*handle) is buggy with destructors. Normal structs
8081
/// with dtors may not be destructured, but tuple structs can,
@@ -83,6 +84,14 @@ pub struct Loop {
8384
priv handle: *uvll::uv_loop_t
8485
}
8586

87+
pub struct Handle(*uvll::uv_handle_t);
88+
89+
impl Watcher for Handle {}
90+
impl NativeHandle<*uvll::uv_handle_t> for Handle {
91+
fn from_native_handle(h: *uvll::uv_handle_t) -> Handle { Handle(h) }
92+
fn native_handle(&self) -> *uvll::uv_handle_t { **self }
93+
}
94+
8695
/// The trait implemented by uv 'watchers' (handles). Watchers are
8796
/// non-owning wrappers around the uv handles and are not completely
8897
/// safe - there may be multiple instances for a single underlying
@@ -160,6 +169,7 @@ pub trait WatcherInterop {
160169
fn install_watcher_data(&mut self);
161170
fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData;
162171
fn drop_watcher_data(&mut self);
172+
fn close(self, cb: NullCallback);
163173
}
164174

165175
impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
@@ -207,6 +217,24 @@ impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
207217
uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
208218
}
209219
}
220+
221+
fn close(self, cb: NullCallback) {
222+
let mut this = self;
223+
{
224+
let data = this.get_watcher_data();
225+
assert!(data.close_cb.is_none());
226+
data.close_cb = Some(cb);
227+
}
228+
229+
unsafe { uvll::close(this.native_handle(), close_cb); }
230+
231+
extern fn close_cb(handle: *uvll::uv_handle_t) {
232+
let mut h: Handle = NativeHandle::from_native_handle(handle);
233+
h.get_watcher_data().close_cb.take_unwrap()();
234+
h.drop_watcher_data();
235+
unsafe { uvll::free_handle(handle as *c_void) }
236+
}
237+
}
210238
}
211239

212240
// XXX: Need to define the error constants like EOF so they can be

branches/try2/src/libstd/rt/uv/net.rs

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use libc::{size_t, ssize_t, c_int, c_void, c_uint};
1313
use rt::uv::uvll;
1414
use rt::uv::uvll::*;
1515
use rt::uv::{AllocCallback, ConnectionCallback, ReadCallback, UdpReceiveCallback, UdpSendCallback};
16-
use rt::uv::{Loop, Watcher, Request, UvError, Buf, NativeHandle, NullCallback,
16+
use rt::uv::{Loop, Watcher, Request, UvError, Buf, NativeHandle,
1717
status_to_maybe_uv_error, vec_to_uv_buf};
1818
use rt::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
1919
use vec;
@@ -184,24 +184,6 @@ impl StreamWatcher {
184184
}
185185
}
186186

187-
pub fn close(self, cb: NullCallback) {
188-
{
189-
let mut this = self;
190-
let data = this.get_watcher_data();
191-
assert!(data.close_cb.is_none());
192-
data.close_cb = Some(cb);
193-
}
194-
195-
unsafe { uvll::close(self.native_handle(), close_cb); }
196-
197-
extern fn close_cb(handle: *uvll::uv_stream_t) {
198-
let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle);
199-
let cb = stream_watcher.get_watcher_data().close_cb.take_unwrap();
200-
stream_watcher.drop_watcher_data();
201-
unsafe { free_handle(handle as *c_void) }
202-
cb();
203-
}
204-
}
205187

206188
pub fn listen(&mut self, cb: ConnectionCallback) -> Result<(), UvError> {
207189
{
@@ -413,25 +395,6 @@ impl UdpWatcher {
413395
cb(udp_watcher, status);
414396
}
415397
}
416-
417-
pub fn close(self, cb: NullCallback) {
418-
{
419-
let mut this = self;
420-
let data = this.get_watcher_data();
421-
assert!(data.close_cb.is_none());
422-
data.close_cb = Some(cb);
423-
}
424-
425-
unsafe { uvll::close(self.native_handle(), close_cb); }
426-
427-
extern fn close_cb(handle: *uvll::uv_udp_t) {
428-
let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle);
429-
let cb = udp_watcher.get_watcher_data().close_cb.take_unwrap();
430-
udp_watcher.drop_watcher_data();
431-
unsafe { free_handle(handle as *c_void) }
432-
cb();
433-
}
434-
}
435398
}
436399

437400
impl NativeHandle<*uvll::uv_udp_t> for UdpWatcher {

0 commit comments

Comments
 (0)