1use core::{mem, ptr};
6
7use crate::{
8 error::ResultExt,
9 header::{bits_safamily_t::sa_family_t, sys_uio::iovec},
10 platform::{
11 PalSocket, Sys,
12 types::{c_char, c_int, c_long, c_uchar, c_uint, c_void, size_t, ssize_t},
13 },
14};
15
16pub use crate::header::bits_socklen_t::socklen_t;
17
18pub mod constants;
19
20#[repr(C)]
22#[derive(Default, CheckVsLibcCrate)]
23pub struct linger {
24 pub l_onoff: c_int,
26 pub l_linger: c_int,
28}
29
30#[repr(C)]
32#[derive(Debug, CheckVsLibcCrate)]
33pub struct msghdr {
34 pub msg_name: *mut c_void,
36 pub msg_namelen: socklen_t,
38 pub msg_iov: *mut iovec,
40 pub msg_iovlen: size_t,
42 pub msg_control: *mut c_void,
44 pub msg_controllen: size_t,
46 pub msg_flags: c_int,
48}
49
50#[repr(C)]
52#[derive(Debug, CheckVsLibcCrate)]
53pub struct cmsghdr {
54 pub cmsg_len: size_t,
56 pub cmsg_level: c_int,
58 pub cmsg_type: c_int,
60}
61
62#[repr(C)]
64#[derive(Default, CheckVsLibcCrate)]
65pub struct sockaddr {
66 pub sa_family: sa_family_t,
68 pub sa_data: [c_char; 14],
70}
71
72const _SS_MAXSIZE: usize = 128;
75const _SS_PADDING: usize = _SS_MAXSIZE - mem::size_of::<sa_family_t>() - mem::size_of::<usize>();
78
79#[repr(C)]
91pub struct sockaddr_storage {
93 pub ss_family: sa_family_t,
95 __ss_pad2: [u8; _SS_PADDING],
96 __ss_align: usize,
97}
98
99pub unsafe extern "C" fn __CMSG_LEN(cmsg: *const cmsghdr) -> ssize_t {
102 ((unsafe { (*cmsg).cmsg_len as size_t } + mem::size_of::<c_long>() - 1)
103 & !(mem::size_of::<c_long>() - 1)) as ssize_t
104}
105
106pub unsafe extern "C" fn __CMSG_NEXT(cmsg: *const cmsghdr) -> *mut c_uchar {
108 unsafe { (cmsg as *mut c_uchar).offset(__CMSG_LEN(cmsg)) }
109}
110
111pub unsafe extern "C" fn __MHDR_END(mhdr: *const msghdr) -> *mut c_uchar {
113 unsafe { ((*mhdr).msg_control.cast::<c_uchar>()).add((*mhdr).msg_controllen) }
114}
115
116#[unsafe(no_mangle)]
118pub unsafe extern "C" fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar {
119 unsafe { (cmsg as *mut c_uchar).add(CMSG_ALIGN(mem::size_of::<cmsghdr>())) }
120}
121
122#[unsafe(no_mangle)]
124pub unsafe extern "C" fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr {
125 if cmsg.is_null() {
126 return unsafe { CMSG_FIRSTHDR(mhdr) };
127 };
128
129 unsafe {
130 let next =
131 cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len) + CMSG_ALIGN(mem::size_of::<cmsghdr>());
132 let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen;
133 if next > max {
134 ptr::null_mut::<cmsghdr>()
135 } else {
136 (cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len)) as *mut cmsghdr
137 }
138 }
139}
140
141#[unsafe(no_mangle)]
143pub unsafe extern "C" fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr {
144 unsafe {
145 if (*mhdr).msg_controllen >= mem::size_of::<cmsghdr>() {
146 (*mhdr).msg_control.cast::<cmsghdr>()
147 } else {
148 ptr::null_mut::<cmsghdr>()
149 }
150 }
151}
152
153#[unsafe(no_mangle)]
154pub unsafe extern "C" fn CMSG_ALIGN(len: size_t) -> size_t {
155 (len + mem::size_of::<size_t>() - 1) & !(mem::size_of::<size_t>() - 1)
156}
157
158#[unsafe(no_mangle)]
160pub unsafe extern "C" fn CMSG_SPACE(len: c_uint) -> c_uint {
161 (unsafe { CMSG_ALIGN(len as size_t) } + unsafe { CMSG_ALIGN(mem::size_of::<cmsghdr>()) })
162 as c_uint
163}
164
165#[unsafe(no_mangle)]
167pub unsafe extern "C" fn CMSG_LEN(length: c_uint) -> c_uint {
168 (unsafe { CMSG_ALIGN(mem::size_of::<cmsghdr>()) } + length as usize) as c_uint
169}
170#[unsafe(no_mangle)]
174pub unsafe extern "C" fn accept(
175 socket: c_int,
176 address: *mut sockaddr,
177 address_len: *mut socklen_t,
178) -> c_int {
179 trace_expr!(
180 unsafe { Sys::accept(socket, address, address_len) }.or_minus_one_errno(),
181 "accept({}, {:p}, {:p})",
182 socket,
183 address,
184 address_len
185 )
186}
187
188#[unsafe(no_mangle)]
190pub unsafe extern "C" fn bind(
191 socket: c_int,
192 address: *const sockaddr,
193 address_len: socklen_t,
194) -> c_int {
195 trace_expr!(
196 unsafe { Sys::bind(socket, address, address_len) }
197 .map(|()| 0)
198 .or_minus_one_errno(),
199 "bind({}, {:p}, {})",
200 socket,
201 address,
202 address_len
203 )
204}
205
206#[unsafe(no_mangle)]
208pub unsafe extern "C" fn connect(
209 socket: c_int,
210 address: *const sockaddr,
211 address_len: socklen_t,
212) -> c_int {
213 trace_expr!(
214 unsafe { Sys::connect(socket, address, address_len) }.or_minus_one_errno(),
215 "connect({}, {:p}, {})",
216 socket,
217 address,
218 address_len
219 )
220}
221
222#[unsafe(no_mangle)]
224pub unsafe extern "C" fn getpeername(
225 socket: c_int,
226 address: *mut sockaddr,
227 address_len: *mut socklen_t,
228) -> c_int {
229 trace_expr!(
230 unsafe { Sys::getpeername(socket, address, address_len) }
231 .map(|()| 0)
232 .or_minus_one_errno(),
233 "getpeername({}, {:p}, {:p})",
234 socket,
235 address,
236 address_len
237 )
238}
239
240#[unsafe(no_mangle)]
242pub unsafe extern "C" fn getsockname(
243 socket: c_int,
244 address: *mut sockaddr,
245 address_len: *mut socklen_t,
246) -> c_int {
247 trace_expr!(
248 unsafe { Sys::getsockname(socket, address, address_len) }
249 .map(|()| 0)
250 .or_minus_one_errno(),
251 "getsockname({}, {:p}, {:p})",
252 socket,
253 address,
254 address_len
255 )
256}
257
258#[unsafe(no_mangle)]
260pub unsafe extern "C" fn getsockopt(
261 socket: c_int,
262 level: c_int,
263 option_name: c_int,
264 option_value: *mut c_void,
265 option_len: *mut socklen_t,
266) -> c_int {
267 trace_expr!(
268 unsafe { Sys::getsockopt(socket, level, option_name, option_value, option_len) }
269 .map(|()| 0)
270 .or_minus_one_errno(),
271 "getsockopt({}, {}, {}, {:p}, {:p})",
272 socket,
273 level,
274 option_name,
275 option_value,
276 option_len
277 )
278}
279
280#[unsafe(no_mangle)]
282pub unsafe extern "C" fn listen(socket: c_int, backlog: c_int) -> c_int {
283 Sys::listen(socket, backlog)
284 .map(|()| 0)
285 .or_minus_one_errno()
286}
287
288#[unsafe(no_mangle)]
290pub unsafe extern "C" fn recv(
291 socket: c_int,
292 buffer: *mut c_void,
293 length: size_t,
294 flags: c_int,
295) -> ssize_t {
296 unsafe {
297 recvfrom(
298 socket,
299 buffer,
300 length,
301 flags,
302 ptr::null_mut(),
303 ptr::null_mut(),
304 )
305 }
306}
307
308#[unsafe(no_mangle)]
310pub unsafe extern "C" fn recvfrom(
311 socket: c_int,
312 buffer: *mut c_void,
313 length: size_t,
314 flags: c_int,
315 address: *mut sockaddr,
316 address_len: *mut socklen_t,
317) -> ssize_t {
318 trace_expr!(
319 unsafe { Sys::recvfrom(socket, buffer, length, flags, address, address_len) }
320 .map(|r| r as ssize_t)
321 .or_minus_one_errno(),
322 "recvfrom({}, {:p}, {}, {:#x}, {:p}, {:p})",
323 socket,
324 buffer,
325 length,
326 flags,
327 address,
328 address_len
329 )
330}
331
332#[unsafe(no_mangle)]
334pub unsafe extern "C" fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t {
335 unsafe { Sys::recvmsg(socket, msg, flags) }
336 .map(|r| r as ssize_t)
337 .or_minus_one_errno()
338}
339
340#[unsafe(no_mangle)]
342pub unsafe extern "C" fn send(
343 socket: c_int,
344 message: *const c_void,
345 length: size_t,
346 flags: c_int,
347) -> ssize_t {
348 unsafe { sendto(socket, message, length, flags, ptr::null(), 0) }
349}
350
351#[unsafe(no_mangle)]
353pub unsafe extern "C" fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t {
354 unsafe { Sys::sendmsg(socket, msg, flags) }
355 .map(|w| w as ssize_t)
356 .or_minus_one_errno()
357}
358
359#[unsafe(no_mangle)]
361pub unsafe extern "C" fn sendto(
362 socket: c_int,
363 message: *const c_void,
364 length: size_t,
365 flags: c_int,
366 dest_addr: *const sockaddr,
367 dest_len: socklen_t,
368) -> ssize_t {
369 trace_expr!(
370 unsafe { Sys::sendto(socket, message, length, flags, dest_addr, dest_len) }
371 .map(|w| w as ssize_t)
372 .or_minus_one_errno(),
373 "sendto({}, {:p}, {}, {:#x}, {:p}, {})",
374 socket,
375 message,
376 length,
377 flags,
378 dest_addr,
379 dest_len
380 )
381}
382
383#[unsafe(no_mangle)]
385pub unsafe extern "C" fn setsockopt(
386 socket: c_int,
387 level: c_int,
388 option_name: c_int,
389 option_value: *const c_void,
390 option_len: socklen_t,
391) -> c_int {
392 trace_expr!(
393 unsafe { Sys::setsockopt(socket, level, option_name, option_value, option_len) }
394 .map(|()| 0)
395 .or_minus_one_errno(),
396 "setsockopt({}, {}, {}, {:p}, {})",
397 socket,
398 level,
399 option_name,
400 option_value,
401 option_len
402 )
403}
404
405#[unsafe(no_mangle)]
407pub unsafe extern "C" fn shutdown(socket: c_int, how: c_int) -> c_int {
408 Sys::shutdown(socket, how).map(|()| 0).or_minus_one_errno()
409}
410
411#[unsafe(no_mangle)]
413pub unsafe extern "C" fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
414 trace_expr!(
415 unsafe { Sys::socket(domain, kind, protocol) }.or_minus_one_errno(),
416 "socket({}, {}, {})",
417 domain,
418 kind,
419 protocol,
420 )
421}
422
423#[unsafe(no_mangle)]
425pub unsafe extern "C" fn socketpair(
426 domain: c_int,
427 kind: c_int,
428 protocol: c_int,
429 sv: *mut c_int,
430) -> c_int {
431 trace_expr!(
432 Sys::socketpair(domain, kind, protocol, unsafe {
433 &mut *sv.cast::<[c_int; 2]>()
434 })
435 .map(|()| 0)
436 .or_minus_one_errno(),
437 "socketpair({}, {}, {}, {:p})",
438 domain,
439 kind,
440 protocol,
441 sv
442 )
443}