From 03e91573c73dbaa6afc905c6b14df4bb327589c9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 6 Jan 2014 14:17:23 -0800 Subject: [PATCH] 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. --- src/libnative/io/file.rs | 8 ++++---- src/libnative/lib.rs | 2 +- src/libstd/io/pipe.rs | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/libnative/io/file.rs b/src/libnative/io/file.rs index 0021dfcb881a..dac1ca98cf9d 100644 --- a/src/libnative/io/file.rs +++ b/src/libnative/io/file.rs @@ -79,10 +79,10 @@ impl FileDesc { pub fn inner_read(&mut self, buf: &mut [u8]) -> Result { #[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)) diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs index 9c30e94194dd..31395216f2b5 100644 --- a/src/libnative/lib.rs +++ b/src/libnative/lib.rs @@ -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; diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs index 2349c64a84b2..e3f2cc2384c2 100644 --- a/src/libstd/io/pipe.rs +++ b/src/libstd/io/pipe.rs @@ -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(()); + }) +}