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 #[unstable(feature = "io_safety", issue = "87074")]
214 impl<T: AsSocket> AsSocket for &T {
216 fn as_socket(&self) -> BorrowedSocket<'_> {
221 #[unstable(feature = "io_safety", issue = "87074")]
222 impl<T: AsSocket> AsSocket for &mut T {
224 fn as_socket(&self) -> BorrowedSocket<'_> {
229 impl AsSocket for BorrowedSocket<'_> {
231 fn as_socket(&self) -> BorrowedSocket<'_> {
236 impl AsSocket for OwnedSocket {
238 fn as_socket(&self) -> BorrowedSocket<'_> {
239 // Safety: `OwnedSocket` and `BorrowedSocket` have the same validity
240 // invariants, and the `BorrowdSocket` is bounded by the lifetime
242 unsafe { BorrowedSocket::borrow_raw_socket(self.as_raw_socket()) }
246 impl AsSocket for crate::net::TcpStream {
248 fn as_socket(&self) -> BorrowedSocket<'_> {
249 unsafe { BorrowedSocket::borrow_raw_socket(self.as_raw_socket()) }
253 impl From<crate::net::TcpStream> for OwnedSocket {
255 fn from(tcp_stream: crate::net::TcpStream) -> OwnedSocket {
256 unsafe { OwnedSocket::from_raw_socket(tcp_stream.into_raw_socket()) }
260 impl From<OwnedSocket> for crate::net::TcpStream {
262 fn from(owned: OwnedSocket) -> Self {
263 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
267 impl AsSocket for crate::net::TcpListener {
269 fn as_socket(&self) -> BorrowedSocket<'_> {
270 unsafe { BorrowedSocket::borrow_raw_socket(self.as_raw_socket()) }
274 impl From<crate::net::TcpListener> for OwnedSocket {
276 fn from(tcp_listener: crate::net::TcpListener) -> OwnedSocket {
277 unsafe { OwnedSocket::from_raw_socket(tcp_listener.into_raw_socket()) }
281 impl From<OwnedSocket> for crate::net::TcpListener {
283 fn from(owned: OwnedSocket) -> Self {
284 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
288 impl AsSocket for crate::net::UdpSocket {
290 fn as_socket(&self) -> BorrowedSocket<'_> {
291 unsafe { BorrowedSocket::borrow_raw_socket(self.as_raw_socket()) }
295 impl From<crate::net::UdpSocket> for OwnedSocket {
297 fn from(udp_socket: crate::net::UdpSocket) -> OwnedSocket {
298 unsafe { OwnedSocket::from_raw_socket(udp_socket.into_raw_socket()) }
302 impl From<OwnedSocket> for crate::net::UdpSocket {
304 fn from(owned: OwnedSocket) -> Self {
305 unsafe { Self::from_raw_socket(owned.into_raw_socket()) }