about summary refs log tree commit diff
path: root/library/std/src/sys/solid
diff options
context:
space:
mode:
authorDenis Smirnov <sd@picodata.io>2023-10-05 16:04:28 +0700
committerDenis Smirnov <sd@picodata.io>2023-10-13 18:12:56 +0700
commitdfadd177a9738de289a3a6d4b39c08d94f384c1a (patch)
tree862fe34c94a231910d11dceadcf5fb58eff4022e /library/std/src/sys/solid
parent130ff8cb6c3d62ed66daf652cbb5323d3f93c4fc (diff)
downloadrust-dfadd177a9738de289a3a6d4b39c08d94f384c1a.tar.gz
rust-dfadd177a9738de289a3a6d4b39c08d94f384c1a.zip
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.

If asynchronous connection was successfully established after EINTR
and before the next connection attempt, OS returns EISCONN that was
handled as an error before. This behavior is fixed now and we handle
it as success.

The problem affects MacOS users: Linux doesn't return EISCONN in this
case, Windows connect() can not be interrupted without an old-fashoin
WSACancelBlockingCall function that is not used in the library.
So current solution gives connect() as OS specific implementation.
Diffstat (limited to 'library/std/src/sys/solid')
-rw-r--r--library/std/src/sys/solid/net.rs11
1 files changed, 7 insertions, 4 deletions
diff --git a/library/std/src/sys/solid/net.rs b/library/std/src/sys/solid/net.rs
index 6adced787f3..1eae0fc0642 100644
--- a/library/std/src/sys/solid/net.rs
+++ b/library/std/src/sys/solid/net.rs
@@ -233,12 +233,15 @@ impl Socket {
         }
     }
 
+    pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
+        let (addr, len) = addr.into_inner();
+        cvt(unsafe { netc::connect(self.0.raw(), addr.as_ptr(), len) })?;
+        Ok(())
+    }
+
     pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
         self.set_nonblocking(true)?;
-        let r = unsafe {
-            let (addr, len) = addr.into_inner();
-            cvt(netc::connect(self.0.raw(), addr.as_ptr(), len))
-        };
+        let r = self.connect(addr);
         self.set_nonblocking(false)?;
 
         match r {