libnative erroneously would attempt to fill the entire buffer in a call to
`read` before returning, when rather it should return immediately because
there's not guaranteed to be any data that will ever be received again.
Close #11328
impl rtio::RtioTcpStream for TcpStream {
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
- let ret = keep_going(buf, |buf, len| {
+ let ret = retry(|| {
unsafe {
libc::recv(self.fd,
- buf as *mut libc::c_void,
- len as wrlen,
- 0) as i64
+ buf.as_ptr() as *mut libc::c_void,
+ buf.len() as wrlen,
+ 0) as libc::c_int
}
});
if ret == 0 {
//peer_name(next_test_ip6());
socket_name(next_test_ip6());
})
+
+ iotest!(fn partial_read() {
+ let addr = next_test_ip4();
+ let (p, c) = Chan::new();
+ do spawn {
+ let mut srv = TcpListener::bind(addr).listen();
+ c.send(());
+ let mut cl = srv.accept().unwrap();
+ cl.write([10]);
+ let mut b = [0];
+ cl.read(b);
+ c.send(());
+ }
+
+ p.recv();
+ let mut c = TcpStream::connect(addr).unwrap();
+ let mut b = [0, ..10];
+ assert_eq!(c.read(b), Some(1));
+ c.write([1]);
+ p.recv();
+ })
}