From 1106282bbc97f17e99be15594fd24d212ebac886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Beauz=C3=A9e-Luyssen?= Date: Tue, 9 Apr 2019 10:19:37 +0200 Subject: [PATCH] libstd: win: Remove calls to SetHandleInformation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function isn't available when targeting UWP. Instead: - Create all sockets with the WSA_FLAG_NO_HANDLE_INHERIT flag The socket created by accept() need not to explicitely disable handle inheritance, since the documentation states «The newly created socket is the socket that will handle the actual connection; it has the same properties as socket s, including the asynchronous events registered with the WSAAsyncSelect or WSAEventSelect functions.» The WSA_FLAG_NO_HANDLE_INHERIT is available starting from Windows 7 (sp1) which matches Rust's target platform for Windows - Pass a boolean flag to allow the 'their' end of pipes to be inheritable directly upon creating it, instead of a later call to SetHandleInformation --- src/libstd/sys/windows/c.rs | 6 +----- src/libstd/sys/windows/net.rs | 16 ++++------------ src/libstd/sys/windows/pipe.rs | 9 ++++++++- src/libstd/sys/windows/process.rs | 7 +------ 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 518eccf754cff..aa4cc41cd8f23 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -132,6 +132,7 @@ impl Clone for WIN32_FIND_DATAW { } pub const WSA_FLAG_OVERLAPPED: DWORD = 0x01; +pub const WSA_FLAG_NO_HANDLE_INHERIT: DWORD = 0x80; pub const WSADESCRIPTION_LEN: usize = 256; pub const WSASYS_STATUS_LEN: usize = 128; @@ -168,8 +169,6 @@ pub const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD; pub const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; -pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001; - pub const PROGRESS_CONTINUE: DWORD = 0; pub const ERROR_FILE_NOT_FOUND: DWORD = 2; @@ -1083,9 +1082,6 @@ extern "system" { pub fn GetUserProfileDirectoryW(hToken: HANDLE, lpProfileDir: LPWSTR, lpcchSize: *mut DWORD) -> BOOL; - pub fn SetHandleInformation(hObject: HANDLE, - dwMask: DWORD, - dwFlags: DWORD) -> BOOL; pub fn CopyFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index 1231fd55e252e..40e3f32734ee7 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -97,12 +97,12 @@ impl Socket { }; let socket = unsafe { match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0, - c::WSA_FLAG_OVERLAPPED) { + c::WSA_FLAG_OVERLAPPED | + c::WSA_FLAG_NO_HANDLE_INHERIT) { c::INVALID_SOCKET => Err(last_error()), n => Ok(Socket(n)), } }?; - socket.set_no_inherit()?; Ok(socket) } @@ -168,7 +168,6 @@ impl Socket { n => Ok(Socket(n)), } }?; - socket.set_no_inherit()?; Ok(socket) } @@ -182,12 +181,12 @@ impl Socket { info.iSocketType, info.iProtocol, &mut info, 0, - c::WSA_FLAG_OVERLAPPED) { + c::WSA_FLAG_OVERLAPPED | + c::WSA_FLAG_NO_HANDLE_INHERIT) { c::INVALID_SOCKET => Err(last_error()), n => Ok(Socket(n)), } }?; - socket.set_no_inherit()?; Ok(socket) } @@ -312,13 +311,6 @@ impl Socket { } } - fn set_no_inherit(&self) -> io::Result<()> { - sys::cvt(unsafe { - c::SetHandleInformation(self.0 as c::HANDLE, - c::HANDLE_FLAG_INHERIT, 0) - }).map(|_| ()) - } - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { let how = match how { Shutdown::Write => c::SD_SEND, diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index b38727830f37f..bf0ccb9757470 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -45,7 +45,7 @@ pub struct Pipes { /// mode. This means that technically speaking it should only ever be used /// with `OVERLAPPED` instances, but also works out ok if it's only ever used /// once at a time (which we do indeed guarantee). -pub fn anon_pipe(ours_readable: bool) -> io::Result { +pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Result { // Note that we specifically do *not* use `CreatePipe` here because // unfortunately the anonymous pipes returned do not support overlapped // operations. Instead, we create a "hopefully unique" name and create a @@ -137,6 +137,13 @@ pub fn anon_pipe(ours_readable: bool) -> io::Result { opts.write(ours_readable); opts.read(!ours_readable); opts.share_mode(0); + let size = mem::size_of::(); + let mut sa = c::SECURITY_ATTRIBUTES { + nLength: size as c::DWORD, + lpSecurityDescriptor: ptr::null_mut(), + bInheritHandle: their_handle_inheritable as i32, + }; + opts.security_attributes(&mut sa); let theirs = File::open(Path::new(&name), &opts)?; let theirs = AnonPipe { inner: theirs.into_handle() }; diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index e39b7ae889025..05e0ca6706453 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -267,13 +267,8 @@ impl Stdio { Stdio::MakePipe => { let ours_readable = stdio_id != c::STD_INPUT_HANDLE; - let pipes = pipe::anon_pipe(ours_readable)?; + let pipes = pipe::anon_pipe(ours_readable, true)?; *pipe = Some(pipes.ours); - cvt(unsafe { - c::SetHandleInformation(pipes.theirs.handle().raw(), - c::HANDLE_FLAG_INHERIT, - c::HANDLE_FLAG_INHERIT) - })?; Ok(pipes.theirs.into_handle()) }