@@ -22,42 +22,43 @@ use sys::cvt;
2222use sys:: handle:: Handle ;
2323use sys_common:: io:: read_to_end_uninitialized;
2424
25- pub struct NoClose ( Option < Handle > ) ;
26-
2725pub enum Output {
28- Console ( NoClose ) ,
29- Pipe ( NoClose ) ,
26+ Console ( c :: HANDLE ) ,
27+ Pipe ( c :: HANDLE ) ,
3028}
3129
3230pub struct Stdin {
33- handle : Output ,
3431 utf8 : Mutex < io:: Cursor < Vec < u8 > > > ,
3532}
36- pub struct Stdout ( Output ) ;
37- pub struct Stderr ( Output ) ;
33+ pub struct Stdout ;
34+ pub struct Stderr ;
3835
3936pub fn get ( handle : c:: DWORD ) -> io:: Result < Output > {
4037 let handle = unsafe { c:: GetStdHandle ( handle) } ;
4138 if handle == c:: INVALID_HANDLE_VALUE {
4239 Err ( io:: Error :: last_os_error ( ) )
4340 } else if handle. is_null ( ) {
44- Err ( io:: Error :: new ( io:: ErrorKind :: Other ,
45- "no stdio handle available for this process" ) )
41+ Err ( io:: Error :: from_raw_os_error ( c:: ERROR_INVALID_HANDLE as i32 ) )
4642 } else {
47- let ret = NoClose :: new ( handle) ;
4843 let mut out = 0 ;
4944 match unsafe { c:: GetConsoleMode ( handle, & mut out) } {
50- 0 => Ok ( Output :: Pipe ( ret ) ) ,
51- _ => Ok ( Output :: Console ( ret ) ) ,
45+ 0 => Ok ( Output :: Pipe ( handle ) ) ,
46+ _ => Ok ( Output :: Console ( handle ) ) ,
5247 }
5348 }
5449}
5550
56- fn write ( out : & Output , data : & [ u8 ] ) -> io:: Result < usize > {
57- let handle = match * out {
58- Output :: Console ( ref c) => c. get ( ) . raw ( ) ,
59- Output :: Pipe ( ref p) => return p. get ( ) . write ( data) ,
51+ fn write ( handle : c:: DWORD , data : & [ u8 ] ) -> io:: Result < usize > {
52+ let handle = match try!( get ( handle) ) {
53+ Output :: Console ( c) => c,
54+ Output :: Pipe ( p) => {
55+ let handle = Handle :: new ( p) ;
56+ let ret = handle. write ( data) ;
57+ handle. into_raw ( ) ;
58+ return ret
59+ }
6060 } ;
61+
6162 // As with stdin on windows, stdout often can't handle writes of large
6263 // sizes. For an example, see #14940. For this reason, don't try to
6364 // write the entire output buffer on windows.
@@ -93,18 +94,20 @@ fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
9394
9495impl Stdin {
9596 pub fn new ( ) -> io:: Result < Stdin > {
96- get ( c:: STD_INPUT_HANDLE ) . map ( |handle| {
97- Stdin {
98- handle : handle,
99- utf8 : Mutex :: new ( Cursor :: new ( Vec :: new ( ) ) ) ,
100- }
97+ Ok ( Stdin {
98+ utf8 : Mutex :: new ( Cursor :: new ( Vec :: new ( ) ) ) ,
10199 } )
102100 }
103101
104102 pub fn read ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
105- let handle = match self . handle {
106- Output :: Console ( ref c) => c. get ( ) . raw ( ) ,
107- Output :: Pipe ( ref p) => return p. get ( ) . read ( buf) ,
103+ let handle = match try!( get ( c:: STD_INPUT_HANDLE ) ) {
104+ Output :: Console ( c) => c,
105+ Output :: Pipe ( p) => {
106+ let handle = Handle :: new ( p) ;
107+ let ret = handle. read ( buf) ;
108+ handle. into_raw ( ) ;
109+ return ret
110+ }
108111 } ;
109112 let mut utf8 = self . utf8 . lock ( ) . unwrap ( ) ;
110113 // Read more if the buffer is empty
@@ -125,11 +128,9 @@ impl Stdin {
125128 Ok ( utf8) => utf8. into_bytes ( ) ,
126129 Err ( ..) => return Err ( invalid_encoding ( ) ) ,
127130 } ;
128- if let Output :: Console ( _) = self . handle {
129- if let Some ( & last_byte) = data. last ( ) {
130- if last_byte == CTRL_Z {
131- data. pop ( ) ;
132- }
131+ if let Some ( & last_byte) = data. last ( ) {
132+ if last_byte == CTRL_Z {
133+ data. pop ( ) ;
133134 }
134135 }
135136 * utf8 = Cursor :: new ( data) ;
@@ -158,11 +159,11 @@ impl<'a> Read for &'a Stdin {
158159
159160impl Stdout {
160161 pub fn new ( ) -> io:: Result < Stdout > {
161- get ( c :: STD_OUTPUT_HANDLE ) . map ( Stdout )
162+ Ok ( Stdout )
162163 }
163164
164165 pub fn write ( & self , data : & [ u8 ] ) -> io:: Result < usize > {
165- write ( & self . 0 , data)
166+ write ( c :: STD_OUTPUT_HANDLE , data)
166167 }
167168
168169 pub fn flush ( & self ) -> io:: Result < ( ) > {
@@ -172,11 +173,11 @@ impl Stdout {
172173
173174impl Stderr {
174175 pub fn new ( ) -> io:: Result < Stderr > {
175- get ( c :: STD_ERROR_HANDLE ) . map ( Stderr )
176+ Ok ( Stderr )
176177 }
177178
178179 pub fn write ( & self , data : & [ u8 ] ) -> io:: Result < usize > {
179- write ( & self . 0 , data)
180+ write ( c :: STD_ERROR_HANDLE , data)
180181 }
181182
182183 pub fn flush ( & self ) -> io:: Result < ( ) > {
@@ -197,27 +198,12 @@ impl io::Write for Stderr {
197198 }
198199}
199200
200- impl NoClose {
201- fn new ( handle : c:: HANDLE ) -> NoClose {
202- NoClose ( Some ( Handle :: new ( handle) ) )
203- }
204-
205- fn get ( & self ) -> & Handle { self . 0 . as_ref ( ) . unwrap ( ) }
206- }
207-
208- impl Drop for NoClose {
209- fn drop ( & mut self ) {
210- self . 0 . take ( ) . unwrap ( ) . into_raw ( ) ;
211- }
212- }
213-
214201impl Output {
215- pub fn handle ( & self ) -> & Handle {
216- let nc = match * self {
217- Output :: Console ( ref c) => c,
218- Output :: Pipe ( ref c) => c,
219- } ;
220- nc. 0 . as_ref ( ) . unwrap ( )
202+ pub fn handle ( & self ) -> c:: HANDLE {
203+ match * self {
204+ Output :: Console ( c) => c,
205+ Output :: Pipe ( c) => c,
206+ }
221207 }
222208}
223209
0 commit comments