about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-07-20 19:28:57 +0200
committerGitHub <noreply@github.com>2024-07-20 19:28:57 +0200
commitb3d682c57713f8303a2c47db963a37a3c67498e0 (patch)
treee6a5f9d2801c2ad5d551f58ebfa24864597d10c8
parentfba6e1e64abf7c251d95e457d737dcda6d2d1748 (diff)
parentfae6037884ec5bd9668e1be07990f4a1fdb9de77 (diff)
downloadrust-b3d682c57713f8303a2c47db963a37a3c67498e0.tar.gz
rust-b3d682c57713f8303a2c47db963a37a3c67498e0.zip
Rollup merge of #127734 - ChrisDenton:netc, r=Mark-Simulacrum
Windows: move BSD socket shims to netc

On Windows we need to alter a few types so that they can be used in the cross-platform socket code. Currently these alterations are spread throughout the `c` module with some more in the `netc` module.

Let's gather all our BSD compatibility shims in the `netc` module so it's all in one place and easier to discover.
-rw-r--r--library/std/src/sys/pal/windows/c.rs97
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt1
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs8
-rw-r--r--library/std/src/sys/pal/windows/net.rs112
4 files changed, 109 insertions, 109 deletions
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 296d19a926d..84f3d6a5399 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -8,7 +8,7 @@
 
 use crate::ffi::CStr;
 use crate::mem;
-use crate::os::raw::{c_char, c_int, c_uint, c_ulong, c_ushort, c_void};
+use crate::os::raw::{c_uint, c_ulong, c_ushort, c_void};
 use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
 use crate::ptr;
 
@@ -19,12 +19,6 @@ pub use windows_sys::*;
 
 pub type WCHAR = u16;
 
-pub type socklen_t = c_int;
-pub type ADDRESS_FAMILY = c_ushort;
-pub use FD_SET as fd_set;
-pub use LINGER as linger;
-pub use TIMEVAL as timeval;
-
 pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::without_provenance_mut(-1i32 as _);
 
 // https://learn.microsoft.com/en-us/cpp/c-runtime-library/exit-success-exit-failure?view=msvc-170
@@ -42,20 +36,6 @@ pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() };
 pub const OBJ_DONT_REPARSE: u32 = windows_sys::OBJ_DONT_REPARSE as u32;
 pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: u32 =
     windows_sys::FRS_ERR_SYSVOL_POPULATE_TIMEOUT as u32;
-pub const AF_INET: c_int = windows_sys::AF_INET as c_int;
-pub const AF_INET6: c_int = windows_sys::AF_INET6 as c_int;
-
-#[repr(C)]
-pub struct ip_mreq {
-    pub imr_multiaddr: in_addr,
-    pub imr_interface: in_addr,
-}
-
-#[repr(C)]
-pub struct ipv6_mreq {
-    pub ipv6mr_multiaddr: in6_addr,
-    pub ipv6mr_interface: c_uint,
-}
 
 // Equivalent to the `NT_SUCCESS` C preprocessor macro.
 // See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
@@ -127,45 +107,6 @@ pub struct MOUNT_POINT_REPARSE_BUFFER {
     pub PathBuffer: WCHAR,
 }
 
-#[repr(C)]
-pub struct SOCKADDR_STORAGE_LH {
-    pub ss_family: ADDRESS_FAMILY,
-    pub __ss_pad1: [c_char; 6],
-    pub __ss_align: i64,
-    pub __ss_pad2: [c_char; 112],
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct sockaddr_in {
-    pub sin_family: ADDRESS_FAMILY,
-    pub sin_port: c_ushort,
-    pub sin_addr: in_addr,
-    pub sin_zero: [c_char; 8],
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct sockaddr_in6 {
-    pub sin6_family: ADDRESS_FAMILY,
-    pub sin6_port: c_ushort,
-    pub sin6_flowinfo: c_ulong,
-    pub sin6_addr: in6_addr,
-    pub sin6_scope_id: c_ulong,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct in_addr {
-    pub s_addr: u32,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct in6_addr {
-    pub s6_addr: [u8; 16],
-}
-
 // Desktop specific functions & types
 cfg_if::cfg_if! {
 if #[cfg(not(target_vendor = "uwp"))] {
@@ -205,42 +146,6 @@ pub unsafe extern "system" fn ReadFileEx(
     )
 }
 
-// POSIX compatibility shims.
-pub unsafe fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int {
-    windows_sys::recv(socket, buf.cast::<u8>(), len, flags)
-}
-pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int {
-    windows_sys::send(socket, buf.cast::<u8>(), len, flags)
-}
-pub unsafe fn recvfrom(
-    socket: SOCKET,
-    buf: *mut c_void,
-    len: c_int,
-    flags: c_int,
-    addr: *mut SOCKADDR,
-    addrlen: *mut c_int,
-) -> c_int {
-    windows_sys::recvfrom(socket, buf.cast::<u8>(), len, flags, addr, addrlen)
-}
-pub unsafe fn sendto(
-    socket: SOCKET,
-    buf: *const c_void,
-    len: c_int,
-    flags: c_int,
-    addr: *const SOCKADDR,
-    addrlen: c_int,
-) -> c_int {
-    windows_sys::sendto(socket, buf.cast::<u8>(), len, flags, addr, addrlen)
-}
-pub unsafe fn getaddrinfo(
-    node: *const c_char,
-    service: *const c_char,
-    hints: *const ADDRINFOA,
-    res: *mut *mut ADDRINFOA,
-) -> c_int {
-    windows_sys::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res)
-}
-
 cfg_if::cfg_if! {
 if #[cfg(not(target_vendor = "uwp"))] {
 pub unsafe fn NtReadFile(
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index 5ad4a3731d8..794e2c90c52 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2059,6 +2059,7 @@ Windows.Win32.Networking.WinSock.SOCK_RDM
 Windows.Win32.Networking.WinSock.SOCK_SEQPACKET
 Windows.Win32.Networking.WinSock.SOCK_STREAM
 Windows.Win32.Networking.WinSock.SOCKADDR
+Windows.Win32.Networking.WinSock.SOCKADDR_STORAGE
 Windows.Win32.Networking.WinSock.SOCKADDR_UN
 Windows.Win32.Networking.WinSock.SOCKET
 Windows.Win32.Networking.WinSock.SOCKET_ERROR
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index fea00fec9ae..eae0f775860 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -2890,6 +2890,14 @@ pub struct SOCKADDR {
 }
 #[repr(C)]
 #[derive(Clone, Copy)]
+pub struct SOCKADDR_STORAGE {
+    pub ss_family: ADDRESS_FAMILY,
+    pub __ss_pad1: [i8; 6],
+    pub __ss_align: i64,
+    pub __ss_pad2: [i8; 112],
+}
+#[repr(C)]
+#[derive(Clone, Copy)]
 pub struct SOCKADDR_UN {
     pub sun_family: ADDRESS_FAMILY,
     pub sun_path: [i8; 108],
diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs
index d51fb56238f..b7ecff032e4 100644
--- a/library/std/src/sys/pal/windows/net.rs
+++ b/library/std/src/sys/pal/windows/net.rs
@@ -17,14 +17,100 @@ use crate::time::Duration;
 
 use core::ffi::{c_int, c_long, c_ulong, c_ushort};
 
+#[allow(non_camel_case_types)]
 pub type wrlen_t = i32;
 
 pub mod netc {
-    pub use crate::sys::c::ADDRESS_FAMILY as sa_family_t;
-    pub use crate::sys::c::ADDRINFOA as addrinfo;
-    pub use crate::sys::c::SOCKADDR as sockaddr;
-    pub use crate::sys::c::SOCKADDR_STORAGE_LH as sockaddr_storage;
-    pub use crate::sys::c::*;
+    //! BSD socket compatibility shim
+    //!
+    //! Some Windows API types are not quite what's expected by our cross-platform
+    //! net code. E.g. naming differences or different pointer types.
+    use crate::sys::c::{self, ADDRESS_FAMILY, ADDRINFOA, SOCKADDR, SOCKET};
+    use core::ffi::{c_char, c_int, c_uint, c_ulong, c_ushort, c_void};
+
+    // re-exports from Windows API bindings.
+    pub use crate::sys::c::{
+        bind, connect, freeaddrinfo, getpeername, getsockname, getsockopt, listen, setsockopt,
+        ADDRESS_FAMILY as sa_family_t, ADDRINFOA as addrinfo, IPPROTO_IP, IPPROTO_IPV6,
+        IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_LOOP, IPV6_V6ONLY,
+        IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_TTL,
+        SOCKADDR as sockaddr, SOCKADDR_STORAGE as sockaddr_storage, SOCK_DGRAM, SOCK_STREAM,
+        SOL_SOCKET, SO_BROADCAST, SO_RCVTIMEO, SO_SNDTIMEO,
+    };
+
+    #[allow(non_camel_case_types)]
+    pub type socklen_t = c_int;
+
+    pub const AF_INET: i32 = c::AF_INET as i32;
+    pub const AF_INET6: i32 = c::AF_INET6 as i32;
+
+    // The following two structs use a union in the generated bindings but
+    // our cross-platform code expects a normal field so it's redefined here.
+    // As a consequence, we also need to redefine other structs that use this struct.
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct in_addr {
+        pub s_addr: u32,
+    }
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct in6_addr {
+        pub s6_addr: [u8; 16],
+    }
+
+    #[repr(C)]
+    pub struct ip_mreq {
+        pub imr_multiaddr: in_addr,
+        pub imr_interface: in_addr,
+    }
+
+    #[repr(C)]
+    pub struct ipv6_mreq {
+        pub ipv6mr_multiaddr: in6_addr,
+        pub ipv6mr_interface: c_uint,
+    }
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct sockaddr_in {
+        pub sin_family: ADDRESS_FAMILY,
+        pub sin_port: c_ushort,
+        pub sin_addr: in_addr,
+        pub sin_zero: [c_char; 8],
+    }
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct sockaddr_in6 {
+        pub sin6_family: ADDRESS_FAMILY,
+        pub sin6_port: c_ushort,
+        pub sin6_flowinfo: c_ulong,
+        pub sin6_addr: in6_addr,
+        pub sin6_scope_id: c_ulong,
+    }
+
+    pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int {
+        unsafe { c::send(socket, buf.cast::<u8>(), len, flags) }
+    }
+    pub unsafe fn sendto(
+        socket: SOCKET,
+        buf: *const c_void,
+        len: c_int,
+        flags: c_int,
+        addr: *const SOCKADDR,
+        addrlen: c_int,
+    ) -> c_int {
+        unsafe { c::sendto(socket, buf.cast::<u8>(), len, flags, addr, addrlen) }
+    }
+    pub unsafe fn getaddrinfo(
+        node: *const c_char,
+        service: *const c_char,
+        hints: *const ADDRINFOA,
+        res: *mut *mut ADDRINFOA,
+    ) -> c_int {
+        unsafe { c::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res) }
+    }
 }
 
 pub struct Socket(OwnedSocket);
@@ -102,8 +188,8 @@ where
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
         let family = match *addr {
-            SocketAddr::V4(..) => c::AF_INET,
-            SocketAddr::V6(..) => c::AF_INET6,
+            SocketAddr::V4(..) => netc::AF_INET,
+            SocketAddr::V6(..) => netc::AF_INET6,
         };
         let socket = unsafe {
             c::WSASocketW(
@@ -157,7 +243,7 @@ impl Socket {
                     return Err(io::Error::ZERO_TIMEOUT);
                 }
 
-                let mut timeout = c::timeval {
+                let mut timeout = c::TIMEVAL {
                     tv_sec: cmp::min(timeout.as_secs(), c_long::MAX as u64) as c_long,
                     tv_usec: timeout.subsec_micros() as c_long,
                 };
@@ -167,7 +253,7 @@ impl Socket {
                 }
 
                 let fds = {
-                    let mut fds = unsafe { mem::zeroed::<c::fd_set>() };
+                    let mut fds = unsafe { mem::zeroed::<c::FD_SET>() };
                     fds.fd_count = 1;
                     fds.fd_array[0] = self.as_raw();
                     fds
@@ -295,8 +381,8 @@ impl Socket {
         buf: &mut [u8],
         flags: c_int,
     ) -> io::Result<(usize, SocketAddr)> {
-        let mut storage = unsafe { mem::zeroed::<c::SOCKADDR_STORAGE_LH>() };
-        let mut addrlen = mem::size_of_val(&storage) as c::socklen_t;
+        let mut storage = unsafe { mem::zeroed::<c::SOCKADDR_STORAGE>() };
+        let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t;
         let length = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
 
         // On unix when a socket is shut down all further reads return 0, so we
@@ -399,7 +485,7 @@ impl Socket {
     }
 
     pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
-        let linger = c::linger {
+        let linger = c::LINGER {
             l_onoff: linger.is_some() as c_ushort,
             l_linger: linger.unwrap_or_default().as_secs() as c_ushort,
         };
@@ -408,7 +494,7 @@ impl Socket {
     }
 
     pub fn linger(&self) -> io::Result<Option<Duration>> {
-        let val: c::linger = net::getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?;
+        let val: c::LINGER = net::getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?;
 
         Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
     }