use libc::c_void;
use std::ptr;
pub(crate) mod c_str;
pub trait FromRaw<T> {
unsafe fn from_raw<'a>(raw: *mut c_void) -> &'a mut T {
assert_not_null!(raw);
unsafe { &mut *(raw as *mut T) }
}
}
pub trait AsRaw {
fn as_raw(&mut self) -> *mut c_void {
self as *mut _ as *mut c_void
}
}
pub trait UnwrapOrNull<T> {
fn unwrap_or_null(&self) -> *const T;
}
impl<T> UnwrapOrNull<T> for Option<*const T> {
fn unwrap_or_null(&self) -> *const T {
self.unwrap_or_else(ptr::null)
}
}
#[cfg(target_os = "linux")]
pub trait UnwrapMutOrNull<T> {
fn unwrap_mut_or_null(&mut self) -> *mut T;
}
#[cfg(target_os = "linux")]
impl<T> UnwrapMutOrNull<T> for Option<*mut T> {
fn unwrap_mut_or_null(&mut self) -> *mut T {
self.unwrap_or_else(ptr::null_mut)
}
}
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
pub(crate) mod bonjour {
use crate::Result;
use libc::{fd_set, suseconds_t, time_t, timeval};
use std::time::Duration;
use std::{mem, ptr};
pub unsafe fn read_select(sock_fd: i32, timeout: Duration) -> Result<u32> {
let mut read_flags: fd_set = unsafe { mem::zeroed() };
unsafe { libc::FD_ZERO(&mut read_flags) };
unsafe { libc::FD_SET(sock_fd, &mut read_flags) };
let tv_sec = timeout.as_secs() as time_t;
let tv_usec = timeout.subsec_micros() as suseconds_t;
let mut timeout = timeval { tv_sec, tv_usec };
let result = unsafe {
libc::select(
sock_fd + 1,
&mut read_flags,
ptr::null_mut(),
ptr::null_mut(),
&mut timeout,
)
};
if result < 0 {
Err("select(): returned error status".into())
} else {
Ok(result as u32)
}
}
}
#[cfg(target_vendor = "pc")]
pub(crate) mod bonjour {
use crate::Result;
use bonjour_sys::{dnssd_sock_t, fd_set, select, timeval};
#[cfg(target_vendor = "apple")]
use std::mem;
use std::ptr;
use std::time::Duration;
pub unsafe fn read_select(sock_fd: dnssd_sock_t, timeout: Duration) -> Result<u32> {
if timeout.as_secs() > i32::MAX as u64 {
return Err(
"Invalid timeout duration, as_secs() value exceeds ::libc::c_long. ".into(),
);
}
let timeout: timeval = timeval {
tv_sec: timeout.as_secs() as ::libc::c_long,
tv_usec: timeout.subsec_micros() as ::libc::c_long,
};
let mut set: fd_set = fd_set {
fd_count: 1,
fd_array: [0; 64],
};
set.fd_array[0] = sock_fd;
let result = unsafe { select(0, &mut set, ptr::null_mut(), &mut set, &timeout) };
if result < 0 {
Err("select(): returned error status".into())
} else {
Ok(result as u32)
}
}
}