diff options
| author | Denis Smirnov <sd@picodata.io> | 2023-10-05 16:04:28 +0700 |
|---|---|---|
| committer | Denis Smirnov <sd@picodata.io> | 2023-10-13 18:12:56 +0700 |
| commit | dfadd177a9738de289a3a6d4b39c08d94f384c1a (patch) | |
| tree | 862fe34c94a231910d11dceadcf5fb58eff4022e /library/std/src/sys/windows | |
| parent | 130ff8cb6c3d62ed66daf652cbb5323d3f93c4fc (diff) | |
| download | rust-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/windows')
| -rw-r--r-- | library/std/src/sys/windows/net.rs | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index 4b7115f97c5..c29b863665f 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -140,13 +140,15 @@ impl Socket { } } + pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { + let (addr, len) = addr.into_inner(); + let result = unsafe { c::connect(self.as_raw(), addr.as_ptr(), len) }; + cvt(result).map(drop) + } + pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { self.set_nonblocking(true)?; - let result = { - let (addr, len) = addr.into_inner(); - let result = unsafe { c::connect(self.as_raw(), addr.as_ptr(), len) }; - cvt(result).map(drop) - }; + let result = self.connect(addr); self.set_nonblocking(false)?; match result { |
