about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-01-06 14:17:23 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-01-06 16:32:51 -0800
commit03e91573c73dbaa6afc905c6b14df4bb327589c9 (patch)
tree5518b4e70db6ece31171438d7eb74ca4393d59bc /src
parent3afa0b97c4ce81b3bbfd1e0dd4a6609742957678 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/libnative/io/file.rs8
-rw-r--r--src/libnative/lib.rs2
-rw-r--r--src/libstd/io/pipe.rs22
3 files changed, 27 insertions, 5 deletions
diff --git a/src/libnative/io/file.rs b/src/libnative/io/file.rs
index 0021dfcb881..dac1ca98cf9 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<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))
diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs
index 9c30e94194d..31395216f2b 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 2349c64a84b..e3f2cc2384c 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(());
+    })
+}