Skip to content

Commit

Permalink
Make TCP connect handle EINTR correctly
Browse files Browse the repository at this point in the history
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.

When we try to call connect() again, the connection can already
be istablished asynchronously and we get EISCONN error. In this
case we should not return error (as we previously did).
  • Loading branch information
darthunix committed Oct 4, 2023
1 parent 42ca6e4 commit e668eb3
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
14 changes: 11 additions & 3 deletions library/std/src/sys/unix/mod.rs
Expand Up @@ -323,10 +323,18 @@ where
F: FnMut() -> T,
{
loop {
match cvt(f()) {
Err(ref e) if e.is_interrupted() => {}
other => return other,
let t = f();
if t.is_minus_one() {
let e = crate::io::Error::last_os_error();
if e.is_interrupted() {
continue;
}
if e.raw_os_error() == Some(libc::EISCONN) {
return Ok(t);
}
return Err(e);
}
return Ok(t);
}
}

Expand Down
1 change: 1 addition & 0 deletions library/std/src/sys_common/net.rs
Expand Up @@ -229,6 +229,7 @@ impl TcpStream {

let (addr, len) = addr.into_inner();
cvt_r(|| unsafe { c::connect(sock.as_raw(), addr.as_ptr(), len) })?;
sock.take_error()?;
Ok(TcpStream { inner: sock })
}

Expand Down

0 comments on commit e668eb3

Please sign in to comment.