use linux_unsafe::int;
pub const SOL_SOCKET: int = 1;
pub const SO_ACCEPTCONN: DirectSockOptReadOnly<int> = unsafe { sockopt_readonly(SOL_SOCKET, 30) };
pub const SO_DOMAIN: DirectSockOptReadOnly<int> = unsafe { sockopt_readonly(SOL_SOCKET, 39) };
pub const SO_DONTROUTE: DirectSockOpt<int> = unsafe { sockopt(SOL_SOCKET, 5) };
pub const SO_KEEPALIVE: DirectSockOpt<int> = unsafe { sockopt(SOL_SOCKET, 9) };
pub unsafe trait SetSockOpt<'a> {
type ExtArg
where
Self: 'a;
type OptVal;
type Result;
fn prepare_setsockopt_args(
&self,
arg: &Self::ExtArg,
) -> (int, int, *const Self::OptVal, linux_unsafe::socklen_t);
fn prepare_setsockopt_result(&self, raw: int) -> Self::Result;
}
pub unsafe trait GetSockOpt<'a> {
type OptVal;
type Result
where
Self: 'a;
fn prepare_getsockopt_args(&self) -> (int, int);
fn prepare_getsockopt_result(&self, retval: int, optval: Self::OptVal) -> Self::Result;
}
pub const unsafe fn sockopt<T>(level: int, optname: int) -> DirectSockOpt<T> {
DirectSockOpt::<T> {
level,
optname,
_phantom: core::marker::PhantomData,
}
}
pub const unsafe fn sockopt_readonly<T>(level: int, optname: int) -> DirectSockOptReadOnly<T> {
DirectSockOptReadOnly(sockopt::<T>(level, optname))
}
pub struct DirectSockOpt<T> {
level: int,
optname: int,
_phantom: core::marker::PhantomData<T>,
}
#[repr(transparent)]
pub struct DirectSockOptReadOnly<T>(DirectSockOpt<T>);
unsafe impl<'a, T: 'a> SetSockOpt<'a> for DirectSockOpt<T> {
type ExtArg = T;
type OptVal = T;
type Result = int;
fn prepare_setsockopt_args(
&self,
arg: &Self::ExtArg,
) -> (int, int, *const Self::OptVal, linux_unsafe::socklen_t) {
(
self.level,
self.optname,
arg as *const Self::OptVal,
core::mem::size_of::<Self::OptVal>() as linux_unsafe::socklen_t,
)
}
fn prepare_setsockopt_result(&self, raw: int) -> Self::Result {
raw
}
}
unsafe impl<'a, T: 'a> GetSockOpt<'a> for DirectSockOpt<T> {
type OptVal = T;
type Result = T;
fn prepare_getsockopt_args(&self) -> (int, int) {
(self.level, self.optname)
}
fn prepare_getsockopt_result(&self, _: int, optval: T) -> Self::Result {
optval
}
}
unsafe impl<'a, T: 'a> GetSockOpt<'a> for DirectSockOptReadOnly<T> {
type OptVal = T;
type Result = T;
fn prepare_getsockopt_args(&self) -> (int, int) {
self.0.prepare_getsockopt_args()
}
fn prepare_getsockopt_result(&self, ret: int, optval: T) -> Self::Result {
self.0.prepare_getsockopt_result(ret, optval)
}
}