Skip to main content

nex_sys/
lib.rs

1//! Cross-platform system helpers and low-level wrappers used internally by the nex crates.
2
3#[cfg(not(target_os = "windows"))]
4mod unix;
5#[cfg(not(target_os = "windows"))]
6pub use self::unix::*;
7
8#[cfg(target_os = "windows")]
9mod windows;
10#[cfg(target_os = "windows")]
11pub use self::windows::*;
12
13/// Any file descriptor on unix, only sockets on Windows.
14pub struct FileDesc {
15    pub fd: CSocket,
16}
17
18impl Drop for FileDesc {
19    fn drop(&mut self) {
20        unsafe {
21            close(self.fd);
22        }
23    }
24}
25
26/// Sends data to a socket, returning the number of bytes sent.
27#[allow(clippy::not_unsafe_ptr_arg_deref)]
28pub fn send_to(
29    socket: CSocket,
30    buffer: &[u8],
31    dst: *const SockAddr,
32    slen: SockLen,
33) -> std::io::Result<usize> {
34    let send_len = retry(&mut || unsafe {
35        sendto(
36            socket,
37            buffer.as_ptr() as Buf,
38            buffer.len() as BufLen,
39            0,
40            dst,
41            slen,
42        )
43    });
44
45    if send_len < 0 {
46        Err(std::io::Error::last_os_error())
47    } else {
48        Ok(send_len as usize)
49    }
50}
51
52/// Receives data from a socket, returning the number of bytes read.
53pub fn recv_from(
54    socket: CSocket,
55    buffer: &mut [u8],
56    caddr: *mut SockAddrStorage,
57) -> std::io::Result<usize> {
58    let mut caddrlen = std::mem::size_of::<SockAddrStorage>() as SockLen;
59    let len = retry(&mut || unsafe {
60        recvfrom(
61            socket,
62            buffer.as_ptr() as MutBuf,
63            buffer.len() as BufLen,
64            0,
65            caddr as *mut SockAddr,
66            &mut caddrlen,
67        )
68    });
69
70    if len < 0 {
71        Err(std::io::Error::last_os_error())
72    } else {
73        Ok(len as usize)
74    }
75}