diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-01-25 05:51:09 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-25 05:51:09 +0100 |
| commit | 687bb583c85a66eec094e7edb07ca314541f2330 (patch) | |
| tree | a4db86466ef74e2157b8dbf77e4b6bf91448a2be /library/std/src/sys | |
| parent | e7825f2b690c9a0d21b6f6d84c404bb53b151b38 (diff) | |
| parent | 83aebf8f7bb6d766f6b68accdc44acb9cea3d57e (diff) | |
| download | rust-687bb583c85a66eec094e7edb07ca314541f2330.tar.gz rust-687bb583c85a66eec094e7edb07ca314541f2330.zip | |
Rollup merge of #88794 - sunfishcode:sunfishcode/try-clone, r=joshtriplett
Add a `try_clone()` function to `OwnedFd`. As suggested in #88564. This adds a `try_clone()` to `OwnedFd` by refactoring the code out of the existing `File`/`Socket` code. r? ``@joshtriplett``
Diffstat (limited to 'library/std/src/sys')
| -rw-r--r-- | library/std/src/sys/unix/fd.rs | 17 | ||||
| -rw-r--r-- | library/std/src/sys/windows/fs.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/windows/handle.rs | 21 | ||||
| -rw-r--r-- | library/std/src/sys/windows/net.rs | 62 |
4 files changed, 11 insertions, 91 deletions
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 2362bff913f..3de7c68a686 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -259,22 +259,9 @@ impl FileDesc { } } + #[inline] pub fn duplicate(&self) -> io::Result<FileDesc> { - // We want to atomically duplicate this file descriptor and set the - // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This - // is a POSIX flag that was added to Linux in 2.6.24. - #[cfg(not(target_os = "espidf"))] - let cmd = libc::F_DUPFD_CLOEXEC; - - // For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics - // will never be supported, as this is a bare metal framework with - // no capabilities for multi-process execution. While F_DUPFD is also - // not supported yet, it might be (currently it returns ENOSYS). - #[cfg(target_os = "espidf")] - let cmd = libc::F_DUPFD; - - let fd = cvt(unsafe { libc::fcntl(self.as_raw_fd(), cmd, 0) })?; - Ok(unsafe { FileDesc::from_raw_fd(fd) }) + Ok(Self(self.0.try_clone()?)) } } diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index dd21c6b4389..028b6b30099 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -460,7 +460,7 @@ impl File { } pub fn duplicate(&self) -> io::Result<File> { - Ok(File { handle: self.handle.duplicate(0, false, c::DUPLICATE_SAME_ACCESS)? }) + Ok(Self { handle: self.handle.try_clone()? }) } fn reparse_point<'a>( diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs index c3a3482f910..daab39bb00c 100644 --- a/library/std/src/sys/windows/handle.rs +++ b/library/std/src/sys/windows/handle.rs @@ -262,26 +262,17 @@ impl Handle { Ok(written as usize) } + pub fn try_clone(&self) -> io::Result<Self> { + Ok(Self(self.0.try_clone()?)) + } + pub fn duplicate( &self, access: c::DWORD, inherit: bool, options: c::DWORD, - ) -> io::Result<Handle> { - let mut ret = 0 as c::HANDLE; - cvt(unsafe { - let cur_proc = c::GetCurrentProcess(); - c::DuplicateHandle( - cur_proc, - self.as_raw_handle(), - cur_proc, - &mut ret, - access, - inherit as c::BOOL, - options, - ) - })?; - unsafe { Ok(Handle::from_raw_handle(ret)) } + ) -> io::Result<Self> { + Ok(Self(self.0.duplicate(access, inherit, options)?)) } } diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index 9c631e7e51c..14d5f15d202 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -134,7 +134,7 @@ impl Socket { unsafe { let socket = Self::from_raw_socket(socket); - socket.set_no_inherit()?; + socket.0.set_no_inherit()?; Ok(socket) } } @@ -213,52 +213,7 @@ impl Socket { } pub fn duplicate(&self) -> io::Result<Socket> { - let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() }; - let result = unsafe { - c::WSADuplicateSocketW(self.as_raw_socket(), c::GetCurrentProcessId(), &mut info) - }; - cvt(result)?; - let socket = unsafe { - c::WSASocketW( - info.iAddressFamily, - info.iSocketType, - info.iProtocol, - &mut info, - 0, - c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT, - ) - }; - - if socket != c::INVALID_SOCKET { - unsafe { Ok(Self::from_inner(OwnedSocket::from_raw_socket(socket))) } - } else { - let error = unsafe { c::WSAGetLastError() }; - - if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL { - return Err(io::Error::from_raw_os_error(error)); - } - - let socket = unsafe { - c::WSASocketW( - info.iAddressFamily, - info.iSocketType, - info.iProtocol, - &mut info, - 0, - c::WSA_FLAG_OVERLAPPED, - ) - }; - - if socket == c::INVALID_SOCKET { - return Err(last_error()); - } - - unsafe { - let socket = Self::from_inner(OwnedSocket::from_raw_socket(socket)); - socket.set_no_inherit()?; - Ok(socket) - } - } + Ok(Self(self.0.try_clone()?)) } fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> { @@ -421,19 +376,6 @@ impl Socket { } } - #[cfg(not(target_vendor = "uwp"))] - fn set_no_inherit(&self) -> io::Result<()> { - sys::cvt(unsafe { - c::SetHandleInformation(self.as_raw_socket() as c::HANDLE, c::HANDLE_FLAG_INHERIT, 0) - }) - .map(drop) - } - - #[cfg(target_vendor = "uwp")] - fn set_no_inherit(&self) -> io::Result<()> { - Err(io::Error::new_const(io::ErrorKind::Unsupported, &"Unavailable on UWP")) - } - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { let how = match how { Shutdown::Write => c::SD_SEND, |
