@@ -44,6 +44,7 @@ pub use self::process::Process;
44
44
// Native I/O implementations
45
45
pub mod file;
46
46
pub mod process;
47
+ pub mod net;
47
48
48
49
type IoResult < T > = Result < T , IoError > ;
49
50
@@ -60,7 +61,20 @@ fn translate_error(errno: i32, detail: bool) -> IoError {
60
61
fn get_err ( errno : i32 ) -> ( io:: IoErrorKind , & ' static str ) {
61
62
match errno {
62
63
libc:: EOF => ( io:: EndOfFile , "end of file" ) ,
63
- _ => ( io:: OtherIoError , "unknown error" ) ,
64
+ libc:: WSAECONNREFUSED => ( io:: ConnectionRefused , "connection refused" ) ,
65
+ libc:: WSAECONNRESET => ( io:: ConnectionReset , "connection reset" ) ,
66
+ libc:: WSAEACCES => ( io:: PermissionDenied , "permission denied" ) ,
67
+ libc:: WSAEWOULDBLOCK =>
68
+ ( io:: ResourceUnavailable , "resource temporarily unavailable" ) ,
69
+ libc:: WSAENOTCONN => ( io:: NotConnected , "not connected" ) ,
70
+ libc:: WSAECONNABORTED => ( io:: ConnectionAborted , "connection aborted" ) ,
71
+ libc:: WSAEADDRNOTAVAIL => ( io:: ConnectionRefused , "address not available" ) ,
72
+ libc:: WSAEADDRINUSE => ( io:: ConnectionRefused , "address in use" ) ,
73
+
74
+ x => {
75
+ debug ! ( "ignoring {}: {}" , x, os:: last_os_error( ) ) ;
76
+ ( io:: OtherIoError , "unknown error" )
77
+ }
64
78
}
65
79
}
66
80
@@ -69,13 +83,25 @@ fn translate_error(errno: i32, detail: bool) -> IoError {
69
83
// XXX: this should probably be a bit more descriptive...
70
84
match errno {
71
85
libc:: EOF => ( io:: EndOfFile , "end of file" ) ,
86
+ libc:: ECONNREFUSED => ( io:: ConnectionRefused , "connection refused" ) ,
87
+ libc:: ECONNRESET => ( io:: ConnectionReset , "connection reset" ) ,
88
+ libc:: EPERM | libc:: EACCES =>
89
+ ( io:: PermissionDenied , "permission denied" ) ,
90
+ libc:: EPIPE => ( io:: BrokenPipe , "broken pipe" ) ,
91
+ libc:: ENOTCONN => ( io:: NotConnected , "not connected" ) ,
92
+ libc:: ECONNABORTED => ( io:: ConnectionAborted , "connection aborted" ) ,
93
+ libc:: EADDRNOTAVAIL => ( io:: ConnectionRefused , "address not available" ) ,
94
+ libc:: EADDRINUSE => ( io:: ConnectionRefused , "address in use" ) ,
72
95
73
96
// These two constants can have the same value on some systems, but
74
97
// different values on others, so we can't use a match clause
75
98
x if x == libc:: EAGAIN || x == libc:: EWOULDBLOCK =>
76
99
( io:: ResourceUnavailable , "resource temporarily unavailable" ) ,
77
100
78
- _ => ( io:: OtherIoError , "unknown error" ) ,
101
+ x => {
102
+ debug ! ( "ignoring {}: {}" , x, os:: last_os_error( ) ) ;
103
+ ( io:: OtherIoError , "unknown error" )
104
+ }
79
105
}
80
106
}
81
107
@@ -121,15 +147,24 @@ fn retry(f: || -> libc::c_int) -> IoResult<libc::c_int> {
121
147
122
148
/// Implementation of rt::rtio's IoFactory trait to generate handles to the
123
149
/// native I/O functionality.
124
- pub struct IoFactory ;
150
+ pub struct IoFactory {
151
+ priv cannot_construct_outside_of_this_module : ( )
152
+ }
153
+
154
+ impl IoFactory {
155
+ pub fn new ( ) -> IoFactory {
156
+ net:: init ( ) ;
157
+ IoFactory { cannot_construct_outside_of_this_module : ( ) }
158
+ }
159
+ }
125
160
126
161
impl rtio:: IoFactory for IoFactory {
127
162
// networking
128
- fn tcp_connect ( & mut self , _addr : SocketAddr ) -> IoResult < ~RtioTcpStream > {
129
- Err ( unimpl ( ) )
163
+ fn tcp_connect ( & mut self , addr : SocketAddr ) -> IoResult < ~RtioTcpStream > {
164
+ net :: TcpStream :: connect ( addr ) . map ( |s| ~s as ~ RtioTcpStream )
130
165
}
131
- fn tcp_bind ( & mut self , _addr : SocketAddr ) -> IoResult < ~RtioTcpListener > {
132
- Err ( unimpl ( ) )
166
+ fn tcp_bind ( & mut self , addr : SocketAddr ) -> IoResult < ~RtioTcpListener > {
167
+ net :: TcpListener :: bind ( addr ) . map ( |s| ~s as ~ RtioTcpListener )
133
168
}
134
169
fn udp_bind ( & mut self , _addr : SocketAddr ) -> IoResult < ~RtioUdpSocket > {
135
170
Err ( unimpl ( ) )
@@ -217,9 +252,7 @@ impl rtio::IoFactory for IoFactory {
217
252
}
218
253
fn tty_open ( & mut self , fd : c_int , _readable : bool ) -> IoResult < ~RtioTTY > {
219
254
if unsafe { libc:: isatty ( fd) } != 0 {
220
- // Don't ever close the stdio file descriptors, nothing good really
221
- // comes of that.
222
- Ok ( ~file:: FileDesc :: new ( fd, fd > libc:: STDERR_FILENO ) as ~RtioTTY )
255
+ Ok ( ~file:: FileDesc :: new ( fd, true ) as ~RtioTTY )
223
256
} else {
224
257
Err ( IoError {
225
258
kind : io:: MismatchedFileTypeForOperation ,
0 commit comments