Skip to content

Commit

Permalink
Auto merge of #26658 - alexcrichton:windows-net-no-inherit, r=aturon
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jul 1, 2015
2 parents 8a599c8 + 8890089 commit d2cf9f9
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 16 deletions.
5 changes: 5 additions & 0 deletions src/libstd/sys/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ pub const STD_INPUT_HANDLE: libc::DWORD = -10i32 as libc::DWORD;
pub const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD;
pub const STD_ERROR_HANDLE: libc::DWORD = -12i32 as libc::DWORD;

pub const HANDLE_FLAG_INHERIT: libc::DWORD = 0x00000001;

#[repr(C)]
#[cfg(target_arch = "x86")]
pub struct WSADATA {
Expand Down Expand Up @@ -408,6 +410,9 @@ extern "system" {
pub fn GetUserProfileDirectoryW(hToken: libc::HANDLE,
lpProfileDir: libc::LPCWSTR,
lpcchSize: *mut libc::DWORD) -> libc::BOOL;
pub fn SetHandleInformation(hObject: libc::HANDLE,
dwMask: libc::DWORD,
dwFlags: libc::DWORD) -> libc::BOOL;
}

// Functions that aren't available on Windows XP, but we still use them and just
Expand Down
45 changes: 29 additions & 16 deletions src/libstd/sys/windows/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,31 @@ impl Socket {
SocketAddr::V4(..) => libc::AF_INET,
SocketAddr::V6(..) => libc::AF_INET6,
};
let socket = unsafe {
c::WSASocketW(fam, ty, 0, 0 as *mut _, 0,
c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT)
};
match socket {
INVALID_SOCKET => Err(last_error()),
n => Ok(Socket(n)),
}
let socket = try!(unsafe {
match c::WSASocketW(fam, ty, 0, 0 as *mut _, 0,
c::WSA_FLAG_OVERLAPPED) {
INVALID_SOCKET => Err(last_error()),
n => Ok(Socket(n)),
}
});
try!(socket.set_no_inherit());
Ok(socket)
}

pub fn accept(&self, storage: *mut libc::sockaddr,
len: *mut libc::socklen_t) -> io::Result<Socket> {
match unsafe { libc::accept(self.0, storage, len) } {
INVALID_SOCKET => Err(last_error()),
n => Ok(Socket(n)),
}
let socket = try!(unsafe {
match libc::accept(self.0, storage, len) {
INVALID_SOCKET => Err(last_error()),
n => Ok(Socket(n)),
}
});
try!(socket.set_no_inherit());
Ok(socket)
}

pub fn duplicate(&self) -> io::Result<Socket> {
unsafe {
let socket = try!(unsafe {
let mut info: c::WSAPROTOCOL_INFO = mem::zeroed();
try!(cvt(c::WSADuplicateSocketW(self.0,
c::GetCurrentProcessId(),
Expand All @@ -110,12 +115,13 @@ impl Socket {
info.iSocketType,
info.iProtocol,
&mut info, 0,
c::WSA_FLAG_OVERLAPPED |
c::WSA_FLAG_NO_HANDLE_INHERIT) {
c::WSA_FLAG_OVERLAPPED) {
INVALID_SOCKET => Err(last_error()),
n => Ok(Socket(n)),
}
}
});
try!(socket.set_no_inherit());
Ok(socket)
}

pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
Expand Down Expand Up @@ -156,6 +162,13 @@ impl Socket {
Ok(Some(Duration::new(secs as u64, nsec as u32)))
}
}

fn set_no_inherit(&self) -> io::Result<()> {
sys::cvt(unsafe {
c::SetHandleInformation(self.0 as libc::HANDLE,
c::HANDLE_FLAG_INHERIT, 0)
}).map(|_| ())
}
}

impl Drop for Socket {
Expand Down

0 comments on commit d2cf9f9

Please sign in to comment.