extern crate libc;
use std::io;
use std::mem;
pub use self::native::{addr_to_sockaddr, close, retry, sockaddr_to_addr};
mod native;
#[cfg(windows)] pub type CSocket = libc::SOCKET;
#[cfg(windows)] pub type BufLen = i32;
#[cfg(not(windows))] pub type CSocket = libc::c_int;
#[cfg(not(windows))] pub type BufLen = libc::size_t;
pub struct FileDesc {
pub fd: CSocket,
}
impl Drop for FileDesc {
fn drop(&mut self) {
unsafe {
close(self.fd);
}
}
}
pub fn send_to(socket: CSocket,
buffer: &[u8],
dst: *const libc::sockaddr,
slen: libc::socklen_t)
-> io::Result<usize> {
let send_len = retry(&mut || unsafe {
libc::sendto(socket,
buffer.as_ptr() as *const libc::c_void,
buffer.len() as BufLen,
0,
dst,
slen)
});
if send_len < 0 {
Err(io::Error::last_os_error())
} else {
Ok(send_len as usize)
}
}
pub fn recv_from(socket: CSocket,
buffer: &mut [u8],
caddr: *mut libc::sockaddr_storage)
-> io::Result<usize> {
let mut caddrlen = mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
let len = retry(&mut || unsafe {
libc::recvfrom(socket,
buffer.as_ptr() as *mut libc::c_void,
buffer.len() as BufLen,
0,
caddr as *mut libc::sockaddr,
&mut caddrlen)
});
if len < 0 {
Err(io::Error::last_os_error())
} else {
Ok(len as usize)
}
}