std/os/windows/io/
socket.rs1#![stable(feature = "io_safety", since = "1.63.0")]
4
5use super::raw::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
6use crate::alloc::Allocator;
7use crate::marker::PhantomData;
8use crate::mem::{self, ManuallyDrop};
9#[cfg(not(target_vendor = "uwp"))]
10use crate::sys::cvt;
11use crate::{fmt, io, sys};
12
13type ValidRawSocket = core::num::niche_types::NotAllOnes<RawSocket>;
15
16#[derive(Copy, Clone)]
30#[repr(transparent)]
31#[rustc_nonnull_optimization_guaranteed]
32#[stable(feature = "io_safety", since = "1.63.0")]
33pub struct BorrowedSocket<'socket> {
34 socket: ValidRawSocket,
35 _phantom: PhantomData<&'socket OwnedSocket>,
36}
37
38#[repr(transparent)]
47#[rustc_nonnull_optimization_guaranteed]
48#[stable(feature = "io_safety", since = "1.63.0")]
49pub struct OwnedSocket {
50 socket: ValidRawSocket,
51}
52
53impl BorrowedSocket<'_> {
54 #[inline]
62 #[track_caller]
63 #[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
64 #[stable(feature = "io_safety", since = "1.63.0")]
65 pub const unsafe fn borrow_raw(socket: RawSocket) -> Self {
66 Self { socket: ValidRawSocket::new(socket).expect("socket != -1"), _phantom: PhantomData }
67 }
68}
69
70impl OwnedSocket {
71 #[stable(feature = "io_safety", since = "1.63.0")]
74 pub fn try_clone(&self) -> io::Result<Self> {
75 self.as_socket().try_clone_to_owned()
76 }
77
78 #[allow(implicit_provenance_casts)]
80 #[cfg(not(target_vendor = "uwp"))]
81 pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
82 cvt(unsafe {
83 sys::c::SetHandleInformation(
84 self.as_raw_socket() as sys::c::HANDLE,
85 sys::c::HANDLE_FLAG_INHERIT,
86 0,
87 )
88 })
89 .map(drop)
90 }
91
92 #[cfg(target_vendor = "uwp")]
93 pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
94 Err(io::const_error!(io::ErrorKind::Unsupported, "unavailable on UWP"))
95 }
96}
97
98impl BorrowedSocket<'_> {
99 #[stable(feature = "io_safety", since = "1.63.0")]
102 pub fn try_clone_to_owned(&self) -> io::Result<OwnedSocket> {
103 let mut info = unsafe { mem::zeroed::<sys::c::WSAPROTOCOL_INFOW>() };
104 let result = unsafe {
105 sys::c::WSADuplicateSocketW(
106 self.as_raw_socket() as sys::c::SOCKET,
107 sys::c::GetCurrentProcessId(),
108 &mut info,
109 )
110 };
111 sys::net::cvt(result)?;
112 let socket = unsafe {
113 sys::c::WSASocketW(
114 info.iAddressFamily,
115 info.iSocketType,
116 info.iProtocol,
117 &info,
118 0,
119 sys::c::WSA_FLAG_OVERLAPPED | sys::c::WSA_FLAG_NO_HANDLE_INHERIT,
120 )
121 };
122
123 if socket != sys::c::INVALID_SOCKET {
124 unsafe { Ok(OwnedSocket::from_raw_socket(socket as RawSocket)) }
125 } else {
126 let error = unsafe { sys::c::WSAGetLastError() };
127
128 if error != sys::c::WSAEPROTOTYPE && error != sys::c::WSAEINVAL {
129 return Err(io::Error::from_raw_os_error(error));
130 }
131
132 let socket = unsafe {
133 sys::c::WSASocketW(
134 info.iAddressFamily,
135 info.iSocketType,
136 info.iProtocol,
137 &info,
138 0,
139 sys::c::WSA_FLAG_OVERLAPPED,
140 )
141 };
142
143 if socket == sys::c::INVALID_SOCKET {
144 return Err(last_error());
145 }
146
147 unsafe {
148 let socket = OwnedSocket::from_raw_socket(socket as RawSocket);
149 socket.set_no_inherit()?;
150 Ok(socket)
151 }
152 }
153 }
154}
155
156fn last_error() -> io::Error {
158 io::Error::from_raw_os_error(unsafe { sys::c::WSAGetLastError() })
159}
160
161#[stable(feature = "io_safety", since = "1.63.0")]
162impl AsRawSocket for BorrowedSocket<'_> {
163 #[inline]
164 fn as_raw_socket(&self) -> RawSocket {
165 self.socket.as_inner()
166 }
167}
168
169#[stable(feature = "io_safety", since = "1.63.0")]
170impl AsRawSocket for OwnedSocket {
171 #[inline]
172 fn as_raw_socket(&self) -> RawSocket {
173 self.socket.as_inner()
174 }
175}
176
177#[stable(feature = "io_safety", since = "1.63.0")]
178impl IntoRawSocket for OwnedSocket {
179 #[inline]
180 fn into_raw_socket(self) -> RawSocket {
181 ManuallyDrop::new(self).socket.as_inner()
182 }
183}
184
185#[stable(feature = "io_safety", since = "1.63.0")]
186impl FromRawSocket for OwnedSocket {
187 #[inline]
188 #[track_caller]
189 unsafe fn from_raw_socket(socket: RawSocket) -> Self {
190 Self { socket: ValidRawSocket::new(socket).expect("socket != -1") }
191 }
192}
193
194#[stable(feature = "io_safety", since = "1.63.0")]
195impl Drop for OwnedSocket {
196 #[inline]
197 fn drop(&mut self) {
198 unsafe {
199 let _ = sys::c::closesocket(self.socket.as_inner() as sys::c::SOCKET);
200 }
201 }
202}
203
204#[stable(feature = "io_safety", since = "1.63.0")]
205impl fmt::Debug for BorrowedSocket<'_> {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 f.debug_struct("BorrowedSocket").field("socket", &self.socket).finish()
208 }
209}
210
211#[stable(feature = "io_safety", since = "1.63.0")]
212impl fmt::Debug for OwnedSocket {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 f.debug_struct("OwnedSocket").field("socket", &self.socket).finish()
215 }
216}
217
218#[stable(feature = "io_safety", since = "1.63.0")]
220pub trait AsSocket {
221 #[stable(feature = "io_safety", since = "1.63.0")]
223 fn as_socket(&self) -> BorrowedSocket<'_>;
224}
225
226#[stable(feature = "io_safety", since = "1.63.0")]
227impl<T: AsSocket> AsSocket for &T {
228 #[inline]
229 fn as_socket(&self) -> BorrowedSocket<'_> {
230 T::as_socket(self)
231 }
232}
233
234#[stable(feature = "io_safety", since = "1.63.0")]
235impl<T: AsSocket> AsSocket for &mut T {
236 #[inline]
237 fn as_socket(&self) -> BorrowedSocket<'_> {
238 T::as_socket(self)
239 }
240}
241
242#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
243impl<T: AsSocket> AsSocket for crate::sync::Arc<T> {
256 #[inline]
257 fn as_socket(&self) -> BorrowedSocket<'_> {
258 (**self).as_socket()
259 }
260}
261
262#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
263impl<T: AsSocket> AsSocket for crate::rc::Rc<T> {
264 #[inline]
265 fn as_socket(&self) -> BorrowedSocket<'_> {
266 (**self).as_socket()
267 }
268}
269
270#[unstable(feature = "unique_rc_arc", issue = "112566")]
271impl<T: AsSocket + ?Sized> AsSocket for crate::rc::UniqueRc<T> {
272 #[inline]
273 fn as_socket(&self) -> BorrowedSocket<'_> {
274 (**self).as_socket()
275 }
276}
277
278#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
279impl<T: AsSocket, A: Allocator> AsSocket for Box<T, A> {
280 #[inline]
281 fn as_socket(&self) -> BorrowedSocket<'_> {
282 (**self).as_socket()
283 }
284}
285
286#[stable(feature = "io_safety", since = "1.63.0")]
287impl AsSocket for BorrowedSocket<'_> {
288 #[inline]
289 fn as_socket(&self) -> BorrowedSocket<'_> {
290 *self
291 }
292}
293
294#[stable(feature = "io_safety", since = "1.63.0")]
295impl AsSocket for OwnedSocket {
296 #[inline]
297 fn as_socket(&self) -> BorrowedSocket<'_> {
298 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
302 }
303}
304
305#[stable(feature = "io_safety", since = "1.63.0")]
306impl AsSocket for crate::net::TcpStream {
307 #[inline]
308 fn as_socket(&self) -> BorrowedSocket<'_> {
309 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
310 }
311}
312
313#[stable(feature = "io_safety", since = "1.63.0")]
314impl From<crate::net::TcpStream> for OwnedSocket {
315 #[inline]
317 fn from(tcp_stream: crate::net::TcpStream) -> OwnedSocket {
318 unsafe { OwnedSocket::from_raw_socket(tcp_stream.into_raw_socket()) }
319 }
320}
321
322#[stable(feature = "io_safety", since = "1.63.0")]
323impl From<OwnedSocket> for crate::net::TcpStream {
324 #[inline]
325 fn from(owned: OwnedSocket) -> Self {
326 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
327 }
328}
329
330#[stable(feature = "io_safety", since = "1.63.0")]
331impl AsSocket for crate::net::TcpListener {
332 #[inline]
333 fn as_socket(&self) -> BorrowedSocket<'_> {
334 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
335 }
336}
337
338#[stable(feature = "io_safety", since = "1.63.0")]
339impl From<crate::net::TcpListener> for OwnedSocket {
340 #[inline]
342 fn from(tcp_listener: crate::net::TcpListener) -> OwnedSocket {
343 unsafe { OwnedSocket::from_raw_socket(tcp_listener.into_raw_socket()) }
344 }
345}
346
347#[stable(feature = "io_safety", since = "1.63.0")]
348impl From<OwnedSocket> for crate::net::TcpListener {
349 #[inline]
350 fn from(owned: OwnedSocket) -> Self {
351 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
352 }
353}
354
355#[stable(feature = "io_safety", since = "1.63.0")]
356impl AsSocket for crate::net::UdpSocket {
357 #[inline]
358 fn as_socket(&self) -> BorrowedSocket<'_> {
359 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
360 }
361}
362
363#[stable(feature = "io_safety", since = "1.63.0")]
364impl From<crate::net::UdpSocket> for OwnedSocket {
365 #[inline]
367 fn from(udp_socket: crate::net::UdpSocket) -> OwnedSocket {
368 unsafe { OwnedSocket::from_raw_socket(udp_socket.into_raw_socket()) }
369 }
370}
371
372#[stable(feature = "io_safety", since = "1.63.0")]
373impl From<OwnedSocket> for crate::net::UdpSocket {
374 #[inline]
375 fn from(owned: OwnedSocket) -> Self {
376 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
377 }
378}