1 //! Owned and borrowed OS sockets.
3 #![stable(feature = "io_safety", since = "1.63.0")]
5 use super::raw::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
8 use crate::marker::PhantomData;
10 use crate::mem::forget;
13 #[cfg(not(target_vendor = "uwp"))]
16 /// A borrowed socket.
18 /// This has a lifetime parameter to tie it to the lifetime of something that
21 /// This uses `repr(transparent)` and has the representation of a host socket,
22 /// so it can be used in FFI in places where a socket is passed as an argument,
23 /// it is not captured or consumed, and it never has the value
26 /// This type's `.to_owned()` implementation returns another `BorrowedSocket`
27 /// rather than an `OwnedSocket`. It just makes a trivial copy of the raw
28 /// socket, which is then borrowed under the same lifetime.
29 #[derive(Copy, Clone)]
31 #[rustc_layout_scalar_valid_range_start(0)]
32 // This is -2, in two's complement. -1 is `INVALID_SOCKET`.
33 #[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))]
35 target_pointer_width = "64",
36 rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
38 #[rustc_nonnull_optimization_guaranteed]
39 #[stable(feature = "io_safety", since = "1.63.0")]
40 pub struct BorrowedSocket<'socket> {
42 _phantom: PhantomData<&'socket OwnedSocket>,
47 /// This closes the socket on drop.
49 /// This uses `repr(transparent)` and has the representation of a host socket,
50 /// so it can be used in FFI in places where a socket is passed as a consumed
51 /// argument or returned as an owned value, and it never has the value
54 #[rustc_layout_scalar_valid_range_start(0)]
55 // This is -2, in two's complement. -1 is `INVALID_SOCKET`.
56 #[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))]
58 target_pointer_width = "64",
59 rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
61 #[rustc_nonnull_optimization_guaranteed]
62 #[stable(feature = "io_safety", since = "1.63.0")]
63 pub struct OwnedSocket {
67 impl BorrowedSocket<'_> {
68 /// Return a `BorrowedSocket` holding the given raw socket.
72 /// The resource pointed to by `raw` must remain open for the duration of
73 /// the returned `BorrowedSocket`, and it must not have the value
76 #[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
77 #[stable(feature = "io_safety", since = "1.63.0")]
78 pub const unsafe fn borrow_raw(socket: RawSocket) -> Self {
79 assert!(socket != c::INVALID_SOCKET as RawSocket);
80 Self { socket, _phantom: PhantomData }
85 /// Creates a new `OwnedSocket` instance that shares the same underlying
86 /// object as the existing `OwnedSocket` instance.
87 #[stable(feature = "io_safety", since = "1.63.0")]
88 pub fn try_clone(&self) -> io::Result<Self> {
89 self.as_socket().try_clone_to_owned()
92 // FIXME(strict_provenance_magic): we defined RawSocket to be a u64 ;-;
93 #[allow(fuzzy_provenance_casts)]
94 #[cfg(not(target_vendor = "uwp"))]
95 pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
97 c::SetHandleInformation(self.as_raw_socket() as c::HANDLE, c::HANDLE_FLAG_INHERIT, 0)
102 #[cfg(target_vendor = "uwp")]
103 pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
104 Err(io::const_io_error!(io::ErrorKind::Unsupported, "Unavailable on UWP"))
108 impl BorrowedSocket<'_> {
109 /// Creates a new `OwnedSocket` instance that shares the same underlying
110 /// object as the existing `BorrowedSocket` instance.
111 #[stable(feature = "io_safety", since = "1.63.0")]
112 pub fn try_clone_to_owned(&self) -> io::Result<OwnedSocket> {
113 let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() };
114 let result = unsafe {
115 c::WSADuplicateSocketW(self.as_raw_socket(), c::GetCurrentProcessId(), &mut info)
117 sys::net::cvt(result)?;
118 let socket = unsafe {
125 c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT,
129 if socket != c::INVALID_SOCKET {
130 unsafe { Ok(OwnedSocket::from_raw_socket(socket)) }
132 let error = unsafe { c::WSAGetLastError() };
134 if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL {
135 return Err(io::Error::from_raw_os_error(error));
138 let socket = unsafe {
145 c::WSA_FLAG_OVERLAPPED,
149 if socket == c::INVALID_SOCKET {
150 return Err(last_error());
154 let socket = OwnedSocket::from_raw_socket(socket);
155 socket.set_no_inherit()?;
162 /// Returns the last error from the Windows socket interface.
163 fn last_error() -> io::Error {
164 io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
167 #[stable(feature = "io_safety", since = "1.63.0")]
168 impl AsRawSocket for BorrowedSocket<'_> {
170 fn as_raw_socket(&self) -> RawSocket {
175 #[stable(feature = "io_safety", since = "1.63.0")]
176 impl AsRawSocket for OwnedSocket {
178 fn as_raw_socket(&self) -> RawSocket {
183 #[stable(feature = "io_safety", since = "1.63.0")]
184 impl IntoRawSocket for OwnedSocket {
186 fn into_raw_socket(self) -> RawSocket {
187 let socket = self.socket;
193 #[stable(feature = "io_safety", since = "1.63.0")]
194 impl FromRawSocket for OwnedSocket {
196 unsafe fn from_raw_socket(socket: RawSocket) -> Self {
197 debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket);
202 #[stable(feature = "io_safety", since = "1.63.0")]
203 impl Drop for OwnedSocket {
207 let _ = c::closesocket(self.socket);
212 #[stable(feature = "io_safety", since = "1.63.0")]
213 impl fmt::Debug for BorrowedSocket<'_> {
214 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215 f.debug_struct("BorrowedSocket").field("socket", &self.socket).finish()
219 #[stable(feature = "io_safety", since = "1.63.0")]
220 impl fmt::Debug for OwnedSocket {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 f.debug_struct("OwnedSocket").field("socket", &self.socket).finish()
226 /// A trait to borrow the socket from an underlying object.
227 #[stable(feature = "io_safety", since = "1.63.0")]
229 /// Borrows the socket.
230 #[stable(feature = "io_safety", since = "1.63.0")]
231 fn as_socket(&self) -> BorrowedSocket<'_>;
234 #[stable(feature = "io_safety", since = "1.63.0")]
235 impl<T: AsSocket> AsSocket for &T {
237 fn as_socket(&self) -> BorrowedSocket<'_> {
242 #[stable(feature = "io_safety", since = "1.63.0")]
243 impl<T: AsSocket> AsSocket for &mut T {
245 fn as_socket(&self) -> BorrowedSocket<'_> {
250 #[stable(feature = "io_safety", since = "1.63.0")]
251 impl AsSocket for BorrowedSocket<'_> {
253 fn as_socket(&self) -> BorrowedSocket<'_> {
258 #[stable(feature = "io_safety", since = "1.63.0")]
259 impl AsSocket for OwnedSocket {
261 fn as_socket(&self) -> BorrowedSocket<'_> {
262 // Safety: `OwnedSocket` and `BorrowedSocket` have the same validity
263 // invariants, and the `BorrowdSocket` is bounded by the lifetime
265 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
269 #[stable(feature = "io_safety", since = "1.63.0")]
270 impl AsSocket for crate::net::TcpStream {
272 fn as_socket(&self) -> BorrowedSocket<'_> {
273 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
277 #[stable(feature = "io_safety", since = "1.63.0")]
278 impl From<crate::net::TcpStream> for OwnedSocket {
280 fn from(tcp_stream: crate::net::TcpStream) -> OwnedSocket {
281 unsafe { OwnedSocket::from_raw_socket(tcp_stream.into_raw_socket()) }
285 #[stable(feature = "io_safety", since = "1.63.0")]
286 impl From<OwnedSocket> for crate::net::TcpStream {
288 fn from(owned: OwnedSocket) -> Self {
289 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
293 #[stable(feature = "io_safety", since = "1.63.0")]
294 impl AsSocket for crate::net::TcpListener {
296 fn as_socket(&self) -> BorrowedSocket<'_> {
297 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
301 #[stable(feature = "io_safety", since = "1.63.0")]
302 impl From<crate::net::TcpListener> for OwnedSocket {
304 fn from(tcp_listener: crate::net::TcpListener) -> OwnedSocket {
305 unsafe { OwnedSocket::from_raw_socket(tcp_listener.into_raw_socket()) }
309 #[stable(feature = "io_safety", since = "1.63.0")]
310 impl From<OwnedSocket> for crate::net::TcpListener {
312 fn from(owned: OwnedSocket) -> Self {
313 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
317 #[stable(feature = "io_safety", since = "1.63.0")]
318 impl AsSocket for crate::net::UdpSocket {
320 fn as_socket(&self) -> BorrowedSocket<'_> {
321 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
325 #[stable(feature = "io_safety", since = "1.63.0")]
326 impl From<crate::net::UdpSocket> for OwnedSocket {
328 fn from(udp_socket: crate::net::UdpSocket) -> OwnedSocket {
329 unsafe { OwnedSocket::from_raw_socket(udp_socket.into_raw_socket()) }
333 #[stable(feature = "io_safety", since = "1.63.0")]
334 impl From<OwnedSocket> for crate::net::UdpSocket {
336 fn from(owned: OwnedSocket) -> Self {
337 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }