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