Don't read forever on a file descriptor

Similarly to the recent commit to do this for networking, there's no reason that
a read on a file descriptor should continue reading until the entire buffer is
full. This makes sense when dealing with literal files, but when dealing with
things like stdin this doesn't make sense.
This commit is contained in:
Alex Crichton 2014-01-06 14:17:23 -08:00
parent 3afa0b97c4
commit 03e91573c7
3 changed files with 27 additions and 5 deletions

View file

@ -79,10 +79,10 @@ impl FileDesc {
pub fn inner_read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
#[cfg(windows)] type rlen = libc::c_uint;
#[cfg(not(windows))] type rlen = libc::size_t;
let ret = keep_going(buf, |buf, len| {
unsafe {
libc::read(self.fd, buf as *mut libc::c_void, len as rlen) as i64
}
let ret = retry(|| unsafe {
libc::read(self.fd,
buf.as_ptr() as *mut libc::c_void,
buf.len() as rlen) as libc::c_int
});
if ret == 0 {
Err(io::standard_error(io::EndOfFile))

View file

@ -34,7 +34,7 @@ pub mod io;
pub mod task;
// XXX: this should not exist here
#[cfg(stage0)]
#[cfg(stage0, nativestart)]
#[lang = "start"]
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
use std::cast;

View file

@ -80,3 +80,25 @@ impl Writer for PipeStream {
}
}
}
#[cfg(test)]
mod test {
iotest!(fn partial_read() {
use os;
use io::pipe::PipeStream;
let os::Pipe { input, out } = os::pipe();
let out = PipeStream::open(out);
let mut input = PipeStream::open(input);
let (p, c) = Chan::new();
do spawn {
let mut out = out;
out.write([10]);
p.recv(); // don't close the pipe until the other read has finished
}
let mut buf = [0, ..10];
input.read(buf);
c.send(());
})
}