Skip to content

Commit 7eeecbc

Browse files
committed
Add SetHandleInformation to Windows
Signed-off-by: John Nunley <[email protected]>
1 parent e6e5c91 commit 7eeecbc

File tree

2 files changed

+52
-24
lines changed

2 files changed

+52
-24
lines changed

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ slab = "0.4.2"
3535
tracing = { version = "0.1.37", default-features = false }
3636
waker-fn = "1.1.0"
3737

38+
[target.'cfg(windows)'.dependencies]
39+
windows-sys = { version = "0.48.0", features = ["Win32_Foundation"] }
40+
3841
[dev-dependencies]
3942
async-channel = "1"
4043
async-net = "1"

src/lib.rs

+49-24
Original file line numberDiff line numberDiff line change
@@ -658,23 +658,7 @@ impl<T: AsFd> Async<T> {
658658
pub fn new(io: T) -> io::Result<Async<T>> {
659659
// Put the file descriptor in non-blocking mode.
660660
let fd = io.as_fd();
661-
cfg_if::cfg_if! {
662-
// ioctl(FIONBIO) sets the flag atomically, but we use this only on Linux
663-
// for now, as with the standard library, because it seems to behave
664-
// differently depending on the platform.
665-
// https://github.com/rust-lang/rust/commit/efeb42be2837842d1beb47b51bb693c7474aba3d
666-
// https://github.com/libuv/libuv/blob/e9d91fccfc3e5ff772d5da90e1c4a24061198ca0/src/unix/poll.c#L78-L80
667-
// https://github.com/tokio-rs/mio/commit/0db49f6d5caf54b12176821363d154384357e70a
668-
if #[cfg(target_os = "linux")] {
669-
rustix::io::ioctl_fionbio(fd, true)?;
670-
} else {
671-
let previous = rustix::fs::fcntl_getfl(fd)?;
672-
let new = previous | rustix::fs::OFlags::NONBLOCK;
673-
if new != previous {
674-
rustix::fs::fcntl_setfl(fd, new)?;
675-
}
676-
}
677-
}
661+
set_nonblocking(fd)?;
678662

679663
// SAFETY: It is impossible to drop the I/O source while it is registered through
680664
// this type.
@@ -2045,6 +2029,8 @@ fn connect(
20452029
domain: rn::AddressFamily,
20462030
protocol: Option<rn::Protocol>,
20472031
) -> io::Result<rustix::fd::OwnedFd> {
2032+
use rustix::fd::AsFd;
2033+
20482034
#[cfg(any(
20492035
target_os = "android",
20502036
target_os = "dragonfly",
@@ -2078,19 +2064,17 @@ fn connect(
20782064
target_os = "ios",
20792065
target_os = "tvos",
20802066
target_os = "watchos",
2067+
target_os = "esp-idf",
20812068
windows,
2082-
target_os = "aix",
2083-
target_os = "haiku"
20842069
)))]
20852070
let flags = rn::SocketFlags::CLOEXEC;
20862071
#[cfg(any(
20872072
target_os = "macos",
20882073
target_os = "ios",
20892074
target_os = "tvos",
20902075
target_os = "watchos",
2076+
target_os = "esp-idf",
20912077
windows,
2092-
target_os = "aix",
2093-
target_os = "haiku"
20942078
))]
20952079
let flags = rn::SocketFlags::empty();
20962080

@@ -2107,7 +2091,7 @@ fn connect(
21072091
rio::fcntl_setfd(&socket, rio::fcntl_getfd(&socket)? | rio::FdFlags::CLOEXEC)?;
21082092

21092093
// Set non-blocking mode.
2110-
rio::ioctl_fionbio(&socket, true)?;
2094+
set_nonblocking(socket.as_fd())?;
21112095

21122096
socket
21132097
};
@@ -2118,16 +2102,57 @@ fn connect(
21182102
target_os = "ios",
21192103
target_os = "tvos",
21202104
target_os = "watchos",
2121-
target_os = "freebsd"
2105+
target_os = "freebsd",
2106+
target_os = "netbsd"
21222107
))]
21232108
rn::sockopt::set_socket_nosigpipe(&socket, true)?;
21242109

2110+
// Set the handle information to HANDLE_FLAG_INHERIT.
2111+
#[cfg(windows)]
2112+
unsafe {
2113+
if windows_sys::Win32::Foundation::SetHandleInformation(
2114+
socket.as_raw_socket() as _,
2115+
windows_sys::Win32::Foundation::HANDLE_FLAG_INHERIT,
2116+
windows_sys::Win32::Foundation::HANDLE_FLAG_INHERIT,
2117+
) == 0
2118+
{
2119+
return Err(io::Error::last_os_error());
2120+
}
2121+
}
2122+
2123+
#[allow(unreachable_patterns)]
21252124
match rn::connect_any(&socket, &addr) {
21262125
Ok(_) => {}
21272126
#[cfg(unix)]
21282127
Err(rio::Errno::INPROGRESS) => {}
2129-
Err(rio::Errno::AGAIN) => {}
2128+
Err(rio::Errno::AGAIN) | Err(rio::Errno::WOULDBLOCK) => {}
21302129
Err(err) => return Err(err.into()),
21312130
}
21322131
Ok(socket)
21332132
}
2133+
2134+
#[inline]
2135+
fn set_nonblocking(
2136+
#[cfg(unix)] fd: BorrowedFd<'_>,
2137+
#[cfg(windows)] fd: BorrowedSocket<'_>,
2138+
) -> io::Result<()> {
2139+
cfg_if::cfg_if! {
2140+
// ioctl(FIONBIO) sets the flag atomically, but we use this only on Linux
2141+
// for now, as with the standard library, because it seems to behave
2142+
// differently depending on the platform.
2143+
// https://github.com/rust-lang/rust/commit/efeb42be2837842d1beb47b51bb693c7474aba3d
2144+
// https://github.com/libuv/libuv/blob/e9d91fccfc3e5ff772d5da90e1c4a24061198ca0/src/unix/poll.c#L78-L80
2145+
// https://github.com/tokio-rs/mio/commit/0db49f6d5caf54b12176821363d154384357e70a
2146+
if #[cfg(any(windows, target_os = "linux"))] {
2147+
rustix::io::ioctl_fionbio(fd, true)?;
2148+
} else {
2149+
let previous = rustix::fs::fcntl_getfl(fd)?;
2150+
let new = previous | rustix::fs::OFlags::NONBLOCK;
2151+
if new != previous {
2152+
rustix::fs::fcntl_setfl(fd, new)?;
2153+
}
2154+
}
2155+
}
2156+
2157+
Ok(())
2158+
}

0 commit comments

Comments
 (0)