about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-01-25 05:51:09 +0100
committerGitHub <noreply@github.com>2022-01-25 05:51:09 +0100
commit687bb583c85a66eec094e7edb07ca314541f2330 (patch)
treea4db86466ef74e2157b8dbf77e4b6bf91448a2be /library/std/src/sys
parente7825f2b690c9a0d21b6f6d84c404bb53b151b38 (diff)
parent83aebf8f7bb6d766f6b68accdc44acb9cea3d57e (diff)
downloadrust-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.rs17
-rw-r--r--library/std/src/sys/windows/fs.rs2
-rw-r--r--library/std/src/sys/windows/handle.rs21
-rw-r--r--library/std/src/sys/windows/net.rs62
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,