Skip to content

Commit 8890089

Browse files
committed
std: Avoid the WSA_FLAG_NO_HANDLE_INHERIT option
This was added after Windows 7 SP1, so it's not always available. Instead use the `SetHandleInformation` function to flag a socket as not inheritable. This is not atomic with respect to creating new processes, but it mirrors what Unix does with respect to possibly using the atomic option in the future. Closes #26543
1 parent c1b8bd2 commit 8890089

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

src/libstd/sys/windows/c.rs

+5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ pub const STD_INPUT_HANDLE: libc::DWORD = -10i32 as libc::DWORD;
6464
pub const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD;
6565
pub const STD_ERROR_HANDLE: libc::DWORD = -12i32 as libc::DWORD;
6666

67+
pub const HANDLE_FLAG_INHERIT: libc::DWORD = 0x00000001;
68+
6769
#[repr(C)]
6870
#[cfg(target_arch = "x86")]
6971
pub struct WSADATA {
@@ -408,6 +410,9 @@ extern "system" {
408410
pub fn GetUserProfileDirectoryW(hToken: libc::HANDLE,
409411
lpProfileDir: libc::LPCWSTR,
410412
lpcchSize: *mut libc::DWORD) -> libc::BOOL;
413+
pub fn SetHandleInformation(hObject: libc::HANDLE,
414+
dwMask: libc::DWORD,
415+
dwFlags: libc::DWORD) -> libc::BOOL;
411416
}
412417

413418
// Functions that aren't available on Windows XP, but we still use them and just

src/libstd/sys/windows/net.rs

+29-16
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,31 @@ impl Socket {
8282
SocketAddr::V4(..) => libc::AF_INET,
8383
SocketAddr::V6(..) => libc::AF_INET6,
8484
};
85-
let socket = unsafe {
86-
c::WSASocketW(fam, ty, 0, 0 as *mut _, 0,
87-
c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT)
88-
};
89-
match socket {
90-
INVALID_SOCKET => Err(last_error()),
91-
n => Ok(Socket(n)),
92-
}
85+
let socket = try!(unsafe {
86+
match c::WSASocketW(fam, ty, 0, 0 as *mut _, 0,
87+
c::WSA_FLAG_OVERLAPPED) {
88+
INVALID_SOCKET => Err(last_error()),
89+
n => Ok(Socket(n)),
90+
}
91+
});
92+
try!(socket.set_no_inherit());
93+
Ok(socket)
9394
}
9495

9596
pub fn accept(&self, storage: *mut libc::sockaddr,
9697
len: *mut libc::socklen_t) -> io::Result<Socket> {
97-
match unsafe { libc::accept(self.0, storage, len) } {
98-
INVALID_SOCKET => Err(last_error()),
99-
n => Ok(Socket(n)),
100-
}
98+
let socket = try!(unsafe {
99+
match libc::accept(self.0, storage, len) {
100+
INVALID_SOCKET => Err(last_error()),
101+
n => Ok(Socket(n)),
102+
}
103+
});
104+
try!(socket.set_no_inherit());
105+
Ok(socket)
101106
}
102107

103108
pub fn duplicate(&self) -> io::Result<Socket> {
104-
unsafe {
109+
let socket = try!(unsafe {
105110
let mut info: c::WSAPROTOCOL_INFO = mem::zeroed();
106111
try!(cvt(c::WSADuplicateSocketW(self.0,
107112
c::GetCurrentProcessId(),
@@ -110,12 +115,13 @@ impl Socket {
110115
info.iSocketType,
111116
info.iProtocol,
112117
&mut info, 0,
113-
c::WSA_FLAG_OVERLAPPED |
114-
c::WSA_FLAG_NO_HANDLE_INHERIT) {
118+
c::WSA_FLAG_OVERLAPPED) {
115119
INVALID_SOCKET => Err(last_error()),
116120
n => Ok(Socket(n)),
117121
}
118-
}
122+
});
123+
try!(socket.set_no_inherit());
124+
Ok(socket)
119125
}
120126

121127
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
@@ -156,6 +162,13 @@ impl Socket {
156162
Ok(Some(Duration::new(secs as u64, nsec as u32)))
157163
}
158164
}
165+
166+
fn set_no_inherit(&self) -> io::Result<()> {
167+
sys::cvt(unsafe {
168+
c::SetHandleInformation(self.0 as libc::HANDLE,
169+
c::HANDLE_FLAG_INHERIT, 0)
170+
}).map(|_| ())
171+
}
159172
}
160173

161174
impl Drop for Socket {

0 commit comments

Comments
 (0)