]> git.lizzy.rs Git - rust.git/commitdiff
Don't read forever on a file descriptor
authorAlex Crichton <alex@alexcrichton.com>
Mon, 6 Jan 2014 22:17:23 +0000 (14:17 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 7 Jan 2014 00:32:51 +0000 (16:32 -0800)
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
src/libnative/lib.rs
src/libstd/io/pipe.rs

index 0021dfcb881a41a5b25436085e773d66fcff1268..dac1ca98cf9d4ef5c097a2767f16df7f301d74ad 100644 (file)
@@ -79,10 +79,10 @@ pub fn new(fd: fd_t, close_on_drop: bool) -> 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))
index 9c30e94194dd25e317c3b5291e90c0ab0360109b..31395216f2b58cae92bafa4ce4d80e413c4dcbe7 100644 (file)
@@ -34,7 +34,7 @@
 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;
index 2349c64a84b272e791849b46dd384d4d4069a795..e3f2cc2384c2713e0b2e342961b7d8bf03a3a309 100644 (file)
@@ -80,3 +80,25 @@ fn write(&mut self, buf: &[u8]) {
         }
     }
 }
+
+#[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(());
+    })
+}