Rollup merge of #127734 - ChrisDenton:netc, r=Mark-Simulacrum · model-checking/verify-rust-std@8fdee23 (original) (raw)

`@@ -17,14 +17,100 @@ use crate::time::Duration;

`

17

17

``

18

18

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

`

19

19

``

``

20

`+

#[allow(non_camel_case_types)]

`

20

21

`pub type wrlen_t = i32;

`

21

22

``

22

23

`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::(), 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::(), 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::(), service.cast::(), hints, res) }

`

``

113

`+

}

`

28

114

`}

`

29

115

``

30

116

`pub struct Socket(OwnedSocket);

`

`@@ -102,8 +188,8 @@ where

`

102

188

`impl Socket {

`

103

189

`pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result {

`

104

190

`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,

`

107

193

`};

`

108

194

`let socket = unsafe {

`

109

195

` c::WSASocketW(

`

`@@ -157,7 +243,7 @@ impl Socket {

`

157

243

`return Err(io::Error::ZERO_TIMEOUT);

`

158

244

`}

`

159

245

``

160

``

`-

let mut timeout = c::timeval {

`

``

246

`+

let mut timeout = c::TIMEVAL {

`

161

247

`tv_sec: cmp::min(timeout.as_secs(), c_long::MAX as u64) as c_long,

`

162

248

`tv_usec: timeout.subsec_micros() as c_long,

`

163

249

`};

`

`@@ -167,7 +253,7 @@ impl Socket {

`

167

253

`}

`

168

254

``

169

255

`let fds = {

`

170

``

`-

let mut fds = unsafe { mem::zeroed::<c::fd_set>() };

`

``

256

`+

let mut fds = unsafe { mem::zeroed::<c::FD_SET>() };

`

171

257

` fds.fd_count = 1;

`

172

258

` fds.fd_array[0] = self.as_raw();

`

173

259

` fds

`

`@@ -295,8 +381,8 @@ impl Socket {

`

295

381

`buf: &mut [u8],

`

296

382

`flags: c_int,

`

297

383

`) -> 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;

`

300

386

`let length = cmp::min(buf.len(), ::MAX as usize) as wrlen_t;

`

301

387

``

302

388

`// On unix when a socket is shut down all further reads return 0, so we

`

`@@ -399,7 +485,7 @@ impl Socket {

`

399

485

`}

`

400

486

``

401

487

`pub fn set_linger(&self, linger: Option) -> io::Result<()> {

`

402

``

`-

let linger = c::linger {

`

``

488

`+

let linger = c::LINGER {

`

403

489

`l_onoff: linger.is_some() as c_ushort,

`

404

490

`l_linger: linger.unwrap_or_default().as_secs() as c_ushort,

`

405

491

`};

`

`@@ -408,7 +494,7 @@ impl Socket {

`

408

494

`}

`

409

495

``

410

496

`pub fn linger(&self) -> io::Result<Option> {

`

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)?;

`

412

498

``

413

499

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

`

414

500

`}

`