Skip to content

Commit f1136b7

Browse files
committed
Make TCP connect handle EINTR correctly
According to the POSIX standard, if connect() is interrupted by a signal that is caught while blocked waiting to establish a connection, connect() shall fail and set errno to EINTR, but the connection request shall not be aborted, and the connection shall be established asynchronously. When the connection has been established asynchronously, select() and poll() shall indicate that the file descriptor for the socket is ready for writing. The previous implementation differs from the recomendation: in a case of the EINTR we tried to reconnect in a loop and sometimes get EISCONN error (this problem was originally detected on MacOS).
1 parent 42ca6e4 commit f1136b7

File tree

1 file changed

+33
-1
lines changed
  • library/std/src/sys_common

1 file changed

+33
-1
lines changed

library/std/src/sys_common/net.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,39 @@ impl TcpStream {
228228
let sock = Socket::new(addr, c::SOCK_STREAM)?;
229229

230230
let (addr, len) = addr.into_inner();
231-
cvt_r(|| unsafe { c::connect(sock.as_raw(), addr.as_ptr(), len) })?;
231+
232+
cfg_if::cfg_if! {
233+
if #[cfg(any(
234+
target_os = "android",
235+
target_os = "linux",
236+
target_os = "windows",
237+
))] {
238+
cvt_r(|| unsafe { c::connect(sock.as_raw(), addr.as_ptr(), len) })?;
239+
} else {
240+
241+
let ret = unsafe { c::connect(sock.as_raw(), addr.as_ptr(), len) };
242+
if ret < 0 {
243+
let err = io::Error::last_os_error();
244+
if !err.is_interrupted() {
245+
return Err(err);
246+
}
247+
248+
let mut pollfd = libc::pollfd { fd: sock.as_raw(), events: libc::POLLOUT, revents: 0 };
249+
loop {
250+
let ret = unsafe { libc::poll(&mut pollfd, 1, -1) };
251+
if ret < 0 {
252+
let err = io::Error::last_os_error();
253+
if err.is_interrupted() {
254+
continue;
255+
}
256+
return Err(err);
257+
}
258+
break;
259+
}
260+
sock.take_error()?;
261+
}
262+
}
263+
}
232264
Ok(TcpStream { inner: sock })
233265
}
234266

0 commit comments

Comments
 (0)