Skip to content

Commit d46c99a

Browse files
committed
std: Funnel read_to_end through to one location
This pushes the implementation detail of proxying `read_to_end` through to `read_to_end_uninitialized` all the way down to the `FileDesc` and `Handle` implementations on Unix/Windows. This way intermediate layers will also be able to take advantage of this optimized implementation. This commit also adds the optimized implementation for `ChildStdout` and `ChildStderr`.
1 parent eabfc16 commit d46c99a

File tree

15 files changed

+136
-11
lines changed

15 files changed

+136
-11
lines changed

src/libstd/fs.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use ffi::OsString;
2222
use io::{self, SeekFrom, Seek, Read, Write};
2323
use path::{Path, PathBuf};
2424
use sys::fs as fs_imp;
25-
use sys_common::io::read_to_end_uninitialized;
2625
use sys_common::{AsInnerMut, FromInner, AsInner, IntoInner};
2726
use vec::Vec;
2827
use time::SystemTime;
@@ -351,7 +350,7 @@ impl Read for File {
351350
self.inner.read(buf)
352351
}
353352
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
354-
unsafe { read_to_end_uninitialized(self, buf) }
353+
self.inner.read_to_end(buf)
355354
}
356355
}
357356
#[stable(feature = "rust1", since = "1.0.0")]
@@ -372,6 +371,9 @@ impl<'a> Read for &'a File {
372371
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
373372
self.inner.read(buf)
374373
}
374+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
375+
self.inner.read_to_end(buf)
376+
}
375377
}
376378
#[stable(feature = "rust1", since = "1.0.0")]
377379
impl<'a> Write for &'a File {

src/libstd/io/stdio.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use io::lazy::Lazy;
1818
use io::{self, BufReader, LineWriter};
1919
use sync::{Arc, Mutex, MutexGuard};
2020
use sys::stdio;
21-
use sys_common::io::{read_to_end_uninitialized};
2221
use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
2322
use thread::LocalKeyState;
2423

@@ -78,6 +77,9 @@ fn stderr_raw() -> io::Result<StderrRaw> { stdio::Stderr::new().map(StderrRaw) }
7877

7978
impl Read for StdinRaw {
8079
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
80+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
81+
self.0.read_to_end(buf)
82+
}
8183
}
8284
impl Write for StdoutRaw {
8385
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
@@ -116,6 +118,12 @@ impl<R: io::Read> io::Read for Maybe<R> {
116118
Maybe::Fake => Ok(0)
117119
}
118120
}
121+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
122+
match *self {
123+
Maybe::Real(ref mut r) => handle_ebadf(r.read_to_end(buf), 0),
124+
Maybe::Fake => Ok(0)
125+
}
126+
}
119127
}
120128

121129
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
@@ -294,7 +302,7 @@ impl<'a> Read for StdinLock<'a> {
294302
self.inner.read(buf)
295303
}
296304
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
297-
unsafe { read_to_end_uninitialized(self, buf) }
305+
self.inner.read_to_end(buf)
298306
}
299307
}
300308

src/libstd/net/tcp.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use io::prelude::*;
1414
use fmt;
1515
use io;
1616
use net::{ToSocketAddrs, SocketAddr, Shutdown};
17-
use sys_common::io::read_to_end_uninitialized;
1817
use sys_common::net as net_imp;
1918
use sys_common::{AsInner, FromInner, IntoInner};
2019
use time::Duration;
@@ -269,7 +268,7 @@ impl TcpStream {
269268
impl Read for TcpStream {
270269
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
271270
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
272-
unsafe { read_to_end_uninitialized(self, buf) }
271+
self.0.read_to_end(buf)
273272
}
274273
}
275274
#[stable(feature = "rust1", since = "1.0.0")]
@@ -281,7 +280,7 @@ impl Write for TcpStream {
281280
impl<'a> Read for &'a TcpStream {
282281
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
283282
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
284-
unsafe { read_to_end_uninitialized(self, buf) }
283+
self.0.read_to_end(buf)
285284
}
286285
}
287286
#[stable(feature = "rust1", since = "1.0.0")]

src/libstd/process.rs

+6
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ impl Read for ChildStdout {
134134
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
135135
self.inner.read(buf)
136136
}
137+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
138+
self.inner.read_to_end(buf)
139+
}
137140
}
138141

139142
impl AsInner<AnonPipe> for ChildStdout {
@@ -161,6 +164,9 @@ impl Read for ChildStderr {
161164
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
162165
self.inner.read(buf)
163166
}
167+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
168+
self.inner.read_to_end(buf)
169+
}
164170
}
165171

166172
impl AsInner<AnonPipe> for ChildStderr {

src/libstd/sys/common/net.rs

+4
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ impl TcpStream {
225225
self.inner.read(buf)
226226
}
227227

228+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
229+
self.inner.read_to_end(buf)
230+
}
231+
228232
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
229233
let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
230234
let ret = try!(cvt(unsafe {

src/libstd/sys/unix/fd.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use io;
11+
use prelude::v1::*;
12+
13+
use io::{self, Read};
1214
use libc::{self, c_int, size_t, c_void};
1315
use mem;
16+
use sync::atomic::{AtomicBool, Ordering};
1417
use sys::cvt;
1518
use sys_common::AsInner;
16-
use sync::atomic::{AtomicBool, Ordering};
19+
use sys_common::io::read_to_end_uninitialized;
1720

1821
pub struct FileDesc {
1922
fd: c_int,
@@ -42,6 +45,11 @@ impl FileDesc {
4245
Ok(ret as usize)
4346
}
4447

48+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
49+
let mut me = self;
50+
(&mut me).read_to_end(buf)
51+
}
52+
4553
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
4654
let ret = try!(cvt(unsafe {
4755
libc::write(self.fd,
@@ -118,6 +126,17 @@ impl FileDesc {
118126
}
119127
}
120128

129+
#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
130+
impl<'a> Read for &'a FileDesc {
131+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
132+
(**self).read(buf)
133+
}
134+
135+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
136+
unsafe { read_to_end_uninitialized(self, buf) }
137+
}
138+
}
139+
121140
impl AsInner<c_int> for FileDesc {
122141
fn as_inner(&self) -> &c_int { &self.fd }
123142
}

src/libstd/sys/unix/fs.rs

+4
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,10 @@ impl File {
486486
self.0.read(buf)
487487
}
488488

489+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
490+
self.0.read_to_end(buf)
491+
}
492+
489493
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
490494
self.0.write(buf)
491495
}

src/libstd/sys/unix/net.rs

+4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ impl Socket {
116116
self.0.read(buf)
117117
}
118118

119+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
120+
self.0.read_to_end(buf)
121+
}
122+
119123
pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
120124
let timeout = match dur {
121125
Some(dur) => {

src/libstd/sys/unix/pipe.rs

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ impl AnonPipe {
5757
self.0.read(buf)
5858
}
5959

60+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
61+
self.0.read_to_end(buf)
62+
}
63+
6064
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
6165
self.0.write(buf)
6266
}

src/libstd/sys/unix/stdio.rs

+9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use prelude::v1::*;
12+
1113
use io;
1214
use libc;
1315
use sys::fd::FileDesc;
@@ -25,6 +27,13 @@ impl Stdin {
2527
fd.into_raw();
2628
ret
2729
}
30+
31+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
32+
let fd = FileDesc::new(libc::STDIN_FILENO);
33+
let ret = fd.read_to_end(buf);
34+
fd.into_raw();
35+
ret
36+
}
2837
}
2938

3039
impl Stdout {

src/libstd/sys/windows/fs.rs

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use prelude::v1::*;
1112
use io::prelude::*;
1213
use os::windows::prelude::*;
1314

@@ -312,6 +313,10 @@ impl File {
312313
self.handle.read(buf)
313314
}
314315

316+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
317+
self.handle.read_to_end(buf)
318+
}
319+
315320
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
316321
self.handle.write(buf)
317322
}

src/libstd/sys/windows/handle.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use prelude::v1::*;
12+
1113
use cmp;
12-
use io::ErrorKind;
14+
use io::{ErrorKind, Read};
1315
use io;
1416
use mem;
1517
use ops::Deref;
1618
use ptr;
1719
use sys::c;
1820
use sys::cvt;
21+
use sys_common::io::read_to_end_uninitialized;
1922
use u32;
2023

2124
/// An owned container for `HANDLE` object, closing them on Drop.
@@ -87,6 +90,11 @@ impl RawHandle {
8790
}
8891
}
8992

93+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
94+
let mut me = self;
95+
(&mut me).read_to_end(buf)
96+
}
97+
9098
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
9199
let mut amt = 0;
92100
// WriteFile takes a DWORD (u32) for the length so it only supports
@@ -111,3 +119,14 @@ impl RawHandle {
111119
Ok(Handle::new(ret))
112120
}
113121
}
122+
123+
#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
124+
impl<'a> Read for &'a RawHandle {
125+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
126+
(**self).read(buf)
127+
}
128+
129+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
130+
unsafe { read_to_end_uninitialized(self, buf) }
131+
}
132+
}

src/libstd/sys/windows/net.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use prelude::v1::*;
12+
1113
use cmp;
12-
use io;
14+
use io::{self, Read};
1315
use libc::{c_int, c_void, c_ulong};
1416
use mem;
1517
use net::{SocketAddr, Shutdown};
@@ -20,6 +22,7 @@ use sync::Once;
2022
use sys::c;
2123
use sys;
2224
use sys_common::{self, AsInner, FromInner, IntoInner};
25+
use sys_common::io::read_to_end_uninitialized;
2326
use sys_common::net;
2427
use time::Duration;
2528

@@ -142,6 +145,11 @@ impl Socket {
142145
}
143146
}
144147

148+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
149+
let mut me = self;
150+
(&mut me).read_to_end(buf)
151+
}
152+
145153
pub fn set_timeout(&self, dur: Option<Duration>,
146154
kind: c_int) -> io::Result<()> {
147155
let timeout = match dur {
@@ -206,6 +214,17 @@ impl Socket {
206214
}
207215
}
208216

217+
#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
218+
impl<'a> Read for &'a Socket {
219+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
220+
(**self).read(buf)
221+
}
222+
223+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
224+
unsafe { read_to_end_uninitialized(self, buf) }
225+
}
226+
}
227+
209228
impl Drop for Socket {
210229
fn drop(&mut self) {
211230
let _ = unsafe { c::closesocket(self.0) };

src/libstd/sys/windows/pipe.rs

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use prelude::v1::*;
12+
1113
use io;
1214
use ptr;
1315
use sys::cvt;
@@ -41,6 +43,10 @@ impl AnonPipe {
4143
self.inner.read(buf)
4244
}
4345

46+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
47+
self.inner.read_to_end(buf)
48+
}
49+
4450
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
4551
self.inner.write(buf)
4652
}

src/libstd/sys/windows/stdio.rs

+17
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use sync::Mutex;
1818
use sys::c;
1919
use sys::cvt;
2020
use sys::handle::Handle;
21+
use sys_common::io::read_to_end_uninitialized;
2122

2223
pub struct NoClose(Option<Handle>);
2324

@@ -113,6 +114,22 @@ impl Stdin {
113114
// MemReader shouldn't error here since we just filled it
114115
utf8.read(buf)
115116
}
117+
118+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
119+
let mut me = self;
120+
(&mut me).read_to_end(buf)
121+
}
122+
}
123+
124+
#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
125+
impl<'a> Read for &'a Stdin {
126+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
127+
(**self).read(buf)
128+
}
129+
130+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
131+
unsafe { read_to_end_uninitialized(self, buf) }
132+
}
116133
}
117134

118135
impl Stdout {

0 commit comments

Comments
 (0)