Skip to content

Commit 0da105a

Browse files
committed
auto merge of #11334 : alexcrichton/rust/fix-native-tcp, r=pcwalton
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
2 parents 8b71b64 + 11e568c commit 0da105a

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

src/libnative/io/net.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,12 @@ impl TcpStream {
275275

276276
impl rtio::RtioTcpStream for TcpStream {
277277
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
278-
let ret = keep_going(buf, |buf, len| {
278+
let ret = retry(|| {
279279
unsafe {
280280
libc::recv(self.fd,
281-
buf as *mut libc::c_void,
282-
len as wrlen,
283-
0) as i64
281+
buf.as_ptr() as *mut libc::c_void,
282+
buf.len() as wrlen,
283+
0) as libc::c_int
284284
}
285285
});
286286
if ret == 0 {

src/libstd/io/net/tcp.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,4 +589,25 @@ mod test {
589589
//peer_name(next_test_ip6());
590590
socket_name(next_test_ip6());
591591
})
592+
593+
iotest!(fn partial_read() {
594+
let addr = next_test_ip4();
595+
let (p, c) = Chan::new();
596+
do spawn {
597+
let mut srv = TcpListener::bind(addr).listen();
598+
c.send(());
599+
let mut cl = srv.accept().unwrap();
600+
cl.write([10]);
601+
let mut b = [0];
602+
cl.read(b);
603+
c.send(());
604+
}
605+
606+
p.recv();
607+
let mut c = TcpStream::connect(addr).unwrap();
608+
let mut b = [0, ..10];
609+
assert_eq!(c.read(b), Some(1));
610+
c.write([1]);
611+
p.recv();
612+
})
592613
}

0 commit comments

Comments
 (0)