1 //! Owned and borrowed OS sockets.
3 #![unstable(feature = "io_safety", issue = "87074")]
5 use super::raw::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
8 use crate::marker::PhantomData;
10 use crate::mem::forget;
15 /// A borrowed socket.
17 /// This has a lifetime parameter to tie it to the lifetime of something that
20 /// This uses `repr(transparent)` and has the representation of a host socket,
21 /// so it can be used in FFI in places where a socket is passed as an argument,
22 /// it is not captured or consumed, and it never has the value
24 #[derive(Copy, Clone)]
26 #[rustc_layout_scalar_valid_range_start(0)]
27 // This is -2, in two's complement. -1 is `INVALID_SOCKET`.
28 #[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))]
30 target_pointer_width = "64",
31 rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
33 #[unstable(feature = "io_safety", issue = "87074")]
34 pub struct BorrowedSocket<'socket> {
36 _phantom: PhantomData<&'socket OwnedSocket>,
41 /// This closes the socket on drop.
43 /// This uses `repr(transparent)` and has the representation of a host socket,
44 /// so it can be used in FFI in places where a socket is passed as a consumed
45 /// argument or returned as an owned value, and it never has the value
48 #[rustc_layout_scalar_valid_range_start(0)]
49 // This is -2, in two's complement. -1 is `INVALID_SOCKET`.
50 #[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))]
52 target_pointer_width = "64",
53 rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
55 #[unstable(feature = "io_safety", issue = "87074")]
56 pub struct OwnedSocket {
60 impl BorrowedSocket<'_> {
61 /// Return a `BorrowedSocket` holding the given raw socket.
65 /// The resource pointed to by `raw` must remain open for the duration of
66 /// the returned `BorrowedSocket`, and it must not have the value
69 #[unstable(feature = "io_safety", issue = "87074")]
70 pub unsafe fn borrow_raw_socket(socket: RawSocket) -> Self {
71 debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket);
72 Self { socket, _phantom: PhantomData }
77 /// Creates a new `OwnedSocket` instance that shares the same underlying socket
78 /// as the existing `OwnedSocket` instance.
79 pub fn try_clone(&self) -> io::Result<Self> {
80 let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() };
82 c::WSADuplicateSocketW(self.as_raw_socket(), c::GetCurrentProcessId(), &mut info)
84 sys::net::cvt(result)?;
92 c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT,
96 if socket != c::INVALID_SOCKET {
97 unsafe { Ok(OwnedSocket::from_raw_socket(socket)) }
99 let error = unsafe { c::WSAGetLastError() };
101 if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL {
102 return Err(io::Error::from_raw_os_error(error));
105 let socket = unsafe {
112 c::WSA_FLAG_OVERLAPPED,
116 if socket == c::INVALID_SOCKET {
117 return Err(last_error());
121 let socket = OwnedSocket::from_raw_socket(socket);
122 socket.set_no_inherit()?;
128 #[cfg(not(target_vendor = "uwp"))]
129 pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
131 c::SetHandleInformation(self.as_raw_socket() as c::HANDLE, c::HANDLE_FLAG_INHERIT, 0)
136 #[cfg(target_vendor = "uwp")]
137 pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
138 Err(io::const_io_error!(io::ErrorKind::Unsupported, "Unavailable on UWP"))
142 /// Returns the last error from the Windows socket interface.
143 fn last_error() -> io::Error {
144 io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
147 impl AsRawSocket for BorrowedSocket<'_> {
149 fn as_raw_socket(&self) -> RawSocket {
154 impl AsRawSocket for OwnedSocket {
156 fn as_raw_socket(&self) -> RawSocket {
161 impl IntoRawSocket for OwnedSocket {
163 fn into_raw_socket(self) -> RawSocket {
164 let socket = self.socket;
170 impl FromRawSocket for OwnedSocket {
171 /// Constructs a new instance of `Self` from the given raw socket.
175 /// The resource pointed to by `socket` must be open and suitable for
176 /// assuming ownership. The resource must not require cleanup other than
179 unsafe fn from_raw_socket(socket: RawSocket) -> Self {
180 debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket);
185 impl Drop for OwnedSocket {
189 let _ = c::closesocket(self.socket);
194 impl fmt::Debug for BorrowedSocket<'_> {
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 f.debug_struct("BorrowedSocket").field("socket", &self.socket).finish()
200 impl fmt::Debug for OwnedSocket {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 f.debug_struct("OwnedSocket").field("socket", &self.socket).finish()
206 /// A trait to borrow the socket from an underlying object.
207 #[unstable(feature = "io_safety", issue = "87074")]
209 /// Borrows the socket.
210 fn as_socket(&self) -> BorrowedSocket<'_>;
213 impl AsSocket for BorrowedSocket<'_> {
215 fn as_socket(&self) -> BorrowedSocket<'_> {
220 impl AsSocket for OwnedSocket {
222 fn as_socket(&self) -> BorrowedSocket<'_> {
223 // Safety: `OwnedSocket` and `BorrowedSocket` have the same validity
224 // invariants, and the `BorrowdSocket` is bounded by the lifetime
226 unsafe { BorrowedSocket::borrow_raw_socket(self.as_raw_socket()) }
230 impl AsSocket for crate::net::TcpStream {
232 fn as_socket(&self) -> BorrowedSocket<'_> {
233 unsafe { BorrowedSocket::borrow_raw_socket(self.as_raw_socket()) }
237 impl From<crate::net::TcpStream> for OwnedSocket {
239 fn from(tcp_stream: crate::net::TcpStream) -> OwnedSocket {
240 unsafe { OwnedSocket::from_raw_socket(tcp_stream.into_raw_socket()) }
244 impl From<OwnedSocket> for crate::net::TcpStream {
246 fn from(owned: OwnedSocket) -> Self {
247 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
251 impl AsSocket for crate::net::TcpListener {
253 fn as_socket(&self) -> BorrowedSocket<'_> {
254 unsafe { BorrowedSocket::borrow_raw_socket(self.as_raw_socket()) }
258 impl From<crate::net::TcpListener> for OwnedSocket {
260 fn from(tcp_listener: crate::net::TcpListener) -> OwnedSocket {
261 unsafe { OwnedSocket::from_raw_socket(tcp_listener.into_raw_socket()) }
265 impl From<OwnedSocket> for crate::net::TcpListener {
267 fn from(owned: OwnedSocket) -> Self {
268 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
272 impl AsSocket for crate::net::UdpSocket {
274 fn as_socket(&self) -> BorrowedSocket<'_> {
275 unsafe { BorrowedSocket::borrow_raw_socket(self.as_raw_socket()) }
279 impl From<crate::net::UdpSocket> for OwnedSocket {
281 fn from(udp_socket: crate::net::UdpSocket) -> OwnedSocket {
282 unsafe { OwnedSocket::from_raw_socket(udp_socket.into_raw_socket()) }
286 impl From<OwnedSocket> for crate::net::UdpSocket {
288 fn from(owned: OwnedSocket) -> Self {
289 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }