Skip to content

Commit 8fdee23

Browse files
authored
Rollup merge of rust-lang#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.
2 parents 07dbb38 + 9bbf09d commit 8fdee23

File tree

4 files changed

+109
-109
lines changed

4 files changed

+109
-109
lines changed

std/src/sys/pal/windows/c.rs

+1-96
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
use crate::ffi::CStr;
1010
use crate::mem;
11-
use crate::os::raw::{c_char, c_int, c_uint, c_ulong, c_ushort, c_void};
11+
use crate::os::raw::{c_uint, c_ulong, c_ushort, c_void};
1212
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
1313
use crate::ptr;
1414

@@ -19,12 +19,6 @@ pub use windows_sys::*;
1919

2020
pub type WCHAR = u16;
2121

22-
pub type socklen_t = c_int;
23-
pub type ADDRESS_FAMILY = c_ushort;
24-
pub use FD_SET as fd_set;
25-
pub use LINGER as linger;
26-
pub use TIMEVAL as timeval;
27-
2822
pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::without_provenance_mut(-1i32 as _);
2923

3024
// 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() };
4236
pub const OBJ_DONT_REPARSE: u32 = windows_sys::OBJ_DONT_REPARSE as u32;
4337
pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: u32 =
4438
windows_sys::FRS_ERR_SYSVOL_POPULATE_TIMEOUT as u32;
45-
pub const AF_INET: c_int = windows_sys::AF_INET as c_int;
46-
pub const AF_INET6: c_int = windows_sys::AF_INET6 as c_int;
47-
48-
#[repr(C)]
49-
pub struct ip_mreq {
50-
pub imr_multiaddr: in_addr,
51-
pub imr_interface: in_addr,
52-
}
53-
54-
#[repr(C)]
55-
pub struct ipv6_mreq {
56-
pub ipv6mr_multiaddr: in6_addr,
57-
pub ipv6mr_interface: c_uint,
58-
}
5939

6040
// Equivalent to the `NT_SUCCESS` C preprocessor macro.
6141
// See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
@@ -127,45 +107,6 @@ pub struct MOUNT_POINT_REPARSE_BUFFER {
127107
pub PathBuffer: WCHAR,
128108
}
129109

130-
#[repr(C)]
131-
pub struct SOCKADDR_STORAGE_LH {
132-
pub ss_family: ADDRESS_FAMILY,
133-
pub __ss_pad1: [c_char; 6],
134-
pub __ss_align: i64,
135-
pub __ss_pad2: [c_char; 112],
136-
}
137-
138-
#[repr(C)]
139-
#[derive(Copy, Clone)]
140-
pub struct sockaddr_in {
141-
pub sin_family: ADDRESS_FAMILY,
142-
pub sin_port: c_ushort,
143-
pub sin_addr: in_addr,
144-
pub sin_zero: [c_char; 8],
145-
}
146-
147-
#[repr(C)]
148-
#[derive(Copy, Clone)]
149-
pub struct sockaddr_in6 {
150-
pub sin6_family: ADDRESS_FAMILY,
151-
pub sin6_port: c_ushort,
152-
pub sin6_flowinfo: c_ulong,
153-
pub sin6_addr: in6_addr,
154-
pub sin6_scope_id: c_ulong,
155-
}
156-
157-
#[repr(C)]
158-
#[derive(Copy, Clone)]
159-
pub struct in_addr {
160-
pub s_addr: u32,
161-
}
162-
163-
#[repr(C)]
164-
#[derive(Copy, Clone)]
165-
pub struct in6_addr {
166-
pub s6_addr: [u8; 16],
167-
}
168-
169110
// Desktop specific functions & types
170111
cfg_if::cfg_if! {
171112
if #[cfg(not(target_vendor = "uwp"))] {
@@ -205,42 +146,6 @@ pub unsafe extern "system" fn ReadFileEx(
205146
)
206147
}
207148

208-
// POSIX compatibility shims.
209-
pub unsafe fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int {
210-
windows_sys::recv(socket, buf.cast::<u8>(), len, flags)
211-
}
212-
pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int {
213-
windows_sys::send(socket, buf.cast::<u8>(), len, flags)
214-
}
215-
pub unsafe fn recvfrom(
216-
socket: SOCKET,
217-
buf: *mut c_void,
218-
len: c_int,
219-
flags: c_int,
220-
addr: *mut SOCKADDR,
221-
addrlen: *mut c_int,
222-
) -> c_int {
223-
windows_sys::recvfrom(socket, buf.cast::<u8>(), len, flags, addr, addrlen)
224-
}
225-
pub unsafe fn sendto(
226-
socket: SOCKET,
227-
buf: *const c_void,
228-
len: c_int,
229-
flags: c_int,
230-
addr: *const SOCKADDR,
231-
addrlen: c_int,
232-
) -> c_int {
233-
windows_sys::sendto(socket, buf.cast::<u8>(), len, flags, addr, addrlen)
234-
}
235-
pub unsafe fn getaddrinfo(
236-
node: *const c_char,
237-
service: *const c_char,
238-
hints: *const ADDRINFOA,
239-
res: *mut *mut ADDRINFOA,
240-
) -> c_int {
241-
windows_sys::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res)
242-
}
243-
244149
cfg_if::cfg_if! {
245150
if #[cfg(not(target_vendor = "uwp"))] {
246151
pub unsafe fn NtReadFile(

std/src/sys/pal/windows/c/bindings.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2059,6 +2059,7 @@ Windows.Win32.Networking.WinSock.SOCK_RDM
20592059
Windows.Win32.Networking.WinSock.SOCK_SEQPACKET
20602060
Windows.Win32.Networking.WinSock.SOCK_STREAM
20612061
Windows.Win32.Networking.WinSock.SOCKADDR
2062+
Windows.Win32.Networking.WinSock.SOCKADDR_STORAGE
20622063
Windows.Win32.Networking.WinSock.SOCKADDR_UN
20632064
Windows.Win32.Networking.WinSock.SOCKET
20642065
Windows.Win32.Networking.WinSock.SOCKET_ERROR

std/src/sys/pal/windows/c/windows_sys.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2890,6 +2890,14 @@ pub struct SOCKADDR {
28902890
}
28912891
#[repr(C)]
28922892
#[derive(Clone, Copy)]
2893+
pub struct SOCKADDR_STORAGE {
2894+
pub ss_family: ADDRESS_FAMILY,
2895+
pub __ss_pad1: [i8; 6],
2896+
pub __ss_align: i64,
2897+
pub __ss_pad2: [i8; 112],
2898+
}
2899+
#[repr(C)]
2900+
#[derive(Clone, Copy)]
28932901
pub struct SOCKADDR_UN {
28942902
pub sun_family: ADDRESS_FAMILY,
28952903
pub sun_path: [i8; 108],

std/src/sys/pal/windows/net.rs

+99-13
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,100 @@ use crate::time::Duration;
1717

1818
use core::ffi::{c_int, c_long, c_ulong, c_ushort};
1919

20+
#[allow(non_camel_case_types)]
2021
pub type wrlen_t = i32;
2122

2223
pub mod netc {
23-
pub use crate::sys::c::ADDRESS_FAMILY as sa_family_t;
24-
pub use crate::sys::c::ADDRINFOA as addrinfo;
25-
pub use crate::sys::c::SOCKADDR as sockaddr;
26-
pub use crate::sys::c::SOCKADDR_STORAGE_LH as sockaddr_storage;
27-
pub use crate::sys::c::*;
24+
//! BSD socket compatibility shim
25+
//!
26+
//! Some Windows API types are not quite what's expected by our cross-platform
27+
//! net code. E.g. naming differences or different pointer types.
28+
use crate::sys::c::{self, ADDRESS_FAMILY, ADDRINFOA, SOCKADDR, SOCKET};
29+
use core::ffi::{c_char, c_int, c_uint, c_ulong, c_ushort, c_void};
30+
31+
// re-exports from Windows API bindings.
32+
pub use crate::sys::c::{
33+
bind, connect, freeaddrinfo, getpeername, getsockname, getsockopt, listen, setsockopt,
34+
ADDRESS_FAMILY as sa_family_t, ADDRINFOA as addrinfo, IPPROTO_IP, IPPROTO_IPV6,
35+
IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_LOOP, IPV6_V6ONLY,
36+
IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_TTL,
37+
SOCKADDR as sockaddr, SOCKADDR_STORAGE as sockaddr_storage, SOCK_DGRAM, SOCK_STREAM,
38+
SOL_SOCKET, SO_BROADCAST, SO_RCVTIMEO, SO_SNDTIMEO,
39+
};
40+
41+
#[allow(non_camel_case_types)]
42+
pub type socklen_t = c_int;
43+
44+
pub const AF_INET: i32 = c::AF_INET as i32;
45+
pub const AF_INET6: i32 = c::AF_INET6 as i32;
46+
47+
// The following two structs use a union in the generated bindings but
48+
// our cross-platform code expects a normal field so it's redefined here.
49+
// As a consequence, we also need to redefine other structs that use this struct.
50+
#[repr(C)]
51+
#[derive(Copy, Clone)]
52+
pub struct in_addr {
53+
pub s_addr: u32,
54+
}
55+
56+
#[repr(C)]
57+
#[derive(Copy, Clone)]
58+
pub struct in6_addr {
59+
pub s6_addr: [u8; 16],
60+
}
61+
62+
#[repr(C)]
63+
pub struct ip_mreq {
64+
pub imr_multiaddr: in_addr,
65+
pub imr_interface: in_addr,
66+
}
67+
68+
#[repr(C)]
69+
pub struct ipv6_mreq {
70+
pub ipv6mr_multiaddr: in6_addr,
71+
pub ipv6mr_interface: c_uint,
72+
}
73+
74+
#[repr(C)]
75+
#[derive(Copy, Clone)]
76+
pub struct sockaddr_in {
77+
pub sin_family: ADDRESS_FAMILY,
78+
pub sin_port: c_ushort,
79+
pub sin_addr: in_addr,
80+
pub sin_zero: [c_char; 8],
81+
}
82+
83+
#[repr(C)]
84+
#[derive(Copy, Clone)]
85+
pub struct sockaddr_in6 {
86+
pub sin6_family: ADDRESS_FAMILY,
87+
pub sin6_port: c_ushort,
88+
pub sin6_flowinfo: c_ulong,
89+
pub sin6_addr: in6_addr,
90+
pub sin6_scope_id: c_ulong,
91+
}
92+
93+
pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int {
94+
unsafe { c::send(socket, buf.cast::<u8>(), len, flags) }
95+
}
96+
pub unsafe fn sendto(
97+
socket: SOCKET,
98+
buf: *const c_void,
99+
len: c_int,
100+
flags: c_int,
101+
addr: *const SOCKADDR,
102+
addrlen: c_int,
103+
) -> c_int {
104+
unsafe { c::sendto(socket, buf.cast::<u8>(), len, flags, addr, addrlen) }
105+
}
106+
pub unsafe fn getaddrinfo(
107+
node: *const c_char,
108+
service: *const c_char,
109+
hints: *const ADDRINFOA,
110+
res: *mut *mut ADDRINFOA,
111+
) -> c_int {
112+
unsafe { c::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res) }
113+
}
28114
}
29115

30116
pub struct Socket(OwnedSocket);
@@ -102,8 +188,8 @@ where
102188
impl Socket {
103189
pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
104190
let family = match *addr {
105-
SocketAddr::V4(..) => c::AF_INET,
106-
SocketAddr::V6(..) => c::AF_INET6,
191+
SocketAddr::V4(..) => netc::AF_INET,
192+
SocketAddr::V6(..) => netc::AF_INET6,
107193
};
108194
let socket = unsafe {
109195
c::WSASocketW(
@@ -157,7 +243,7 @@ impl Socket {
157243
return Err(io::Error::ZERO_TIMEOUT);
158244
}
159245

160-
let mut timeout = c::timeval {
246+
let mut timeout = c::TIMEVAL {
161247
tv_sec: cmp::min(timeout.as_secs(), c_long::MAX as u64) as c_long,
162248
tv_usec: timeout.subsec_micros() as c_long,
163249
};
@@ -167,7 +253,7 @@ impl Socket {
167253
}
168254

169255
let fds = {
170-
let mut fds = unsafe { mem::zeroed::<c::fd_set>() };
256+
let mut fds = unsafe { mem::zeroed::<c::FD_SET>() };
171257
fds.fd_count = 1;
172258
fds.fd_array[0] = self.as_raw();
173259
fds
@@ -295,8 +381,8 @@ impl Socket {
295381
buf: &mut [u8],
296382
flags: c_int,
297383
) -> io::Result<(usize, SocketAddr)> {
298-
let mut storage = unsafe { mem::zeroed::<c::SOCKADDR_STORAGE_LH>() };
299-
let mut addrlen = mem::size_of_val(&storage) as c::socklen_t;
384+
let mut storage = unsafe { mem::zeroed::<c::SOCKADDR_STORAGE>() };
385+
let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t;
300386
let length = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
301387

302388
// On unix when a socket is shut down all further reads return 0, so we
@@ -399,7 +485,7 @@ impl Socket {
399485
}
400486

401487
pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
402-
let linger = c::linger {
488+
let linger = c::LINGER {
403489
l_onoff: linger.is_some() as c_ushort,
404490
l_linger: linger.unwrap_or_default().as_secs() as c_ushort,
405491
};
@@ -408,7 +494,7 @@ impl Socket {
408494
}
409495

410496
pub fn linger(&self) -> io::Result<Option<Duration>> {
411-
let val: c::linger = net::getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?;
497+
let val: c::LINGER = net::getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?;
412498

413499
Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
414500
}

0 commit comments

Comments
 (0)