diff options
author | Frank Denis <github@pureftpd.org> | 2016-01-21 18:27:40 +0100 |
---|---|---|
committer | Kamal Marhubi <kamal@marhubi.com> | 2016-01-29 16:48:08 -0500 |
commit | dc61f352f6b48503fb7ded86c87c84db62d8292c (patch) | |
tree | 6f67b61232bfa2f34e9195b46c9d67095be03fda /src | |
parent | cdb5eac697766720c7d848b29b47da169e13bee7 (diff) | |
download | nix-dc61f352f6b48503fb7ded86c87c84db62d8292c.zip |
Add support for SO_{RCV,SND}BUF(FORCE)? sockopts
Diffstat (limited to 'src')
-rw-r--r-- | src/sys/socket/sockopt.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index f0845033..e6c0f1ad 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -59,6 +59,10 @@ macro_rules! sockopt_impl { sockopt_impl!(GetOnly, $name, $level, $flag, u8, GetU8); }; + (GetOnly, $name:ident, $level:path, $flag:path, usize) => { + sockopt_impl!(GetOnly, $name, $level, $flag, usize, GetUsize); + }; + (GetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => { #[derive(Copy, Clone, Debug)] pub struct $name; @@ -78,6 +82,10 @@ macro_rules! sockopt_impl { sockopt_impl!(SetOnly, $name, $level, $flag, u8, SetU8); }; + (SetOnly, $name:ident, $level:path, $flag:path, usize) => { + sockopt_impl!(SetOnly, $name, $level, $flag, usize, SetUsize); + }; + (SetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => { #[derive(Copy, Clone, Debug)] pub struct $name; @@ -101,6 +109,10 @@ macro_rules! sockopt_impl { sockopt_impl!(Both, $name, $level, $flag, u8, GetU8, SetU8); }; + (Both, $name:ident, $level:path, $flag:path, usize) => { + sockopt_impl!(Both, $name, $level, $flag, usize, GetUsize, SetUsize); + }; + (Both, $name:ident, $level:path, $flag:path, $ty:ty) => { sockopt_impl!(Both, $name, $level, $flag, $ty, GetStruct<$ty>, SetStruct<$ty>); }; @@ -145,6 +157,12 @@ sockopt_impl!(Both, TcpKeepAlive, consts::IPPROTO_TCP, consts::TCP_KEEPALIVE, u3 target_os = "android", target_os = "nacl"))] sockopt_impl!(Both, TcpKeepIdle, consts::IPPROTO_TCP, consts::TCP_KEEPIDLE, u32); +sockopt_impl!(Both, RcvBuf, consts::SOL_SOCKET, consts::SO_RCVBUF, usize); +sockopt_impl!(Both, SndBuf, consts::SOL_SOCKET, consts::SO_SNDBUF, usize); +#[cfg(target_os = "linux")] +sockopt_impl!(SetOnly, RcvBufForce, consts::SOL_SOCKET, consts::SO_RCVBUFFORCE, usize); +#[cfg(target_os = "linux")] +sockopt_impl!(SetOnly, SndBufForce, consts::SOL_SOCKET, consts::SO_SNDBUFFORCE, usize); /* * @@ -300,6 +318,50 @@ impl<'a> Set<'a, u8> for SetU8 { } } +struct GetUsize { + len: socklen_t, + val: c_int, +} + +impl Get<usize> for GetUsize { + unsafe fn blank() -> Self { + GetUsize { + len: mem::size_of::<c_int>() as socklen_t, + val: mem::zeroed(), + } + } + + unsafe fn ffi_ptr(&mut self) -> *mut c_void { + mem::transmute(&mut self.val) + } + + unsafe fn ffi_len(&mut self) -> *mut socklen_t { + mem::transmute(&mut self.len) + } + + unsafe fn unwrap(self) -> usize { + assert!(self.len as usize == mem::size_of::<c_int>(), "invalid getsockopt implementation"); + self.val as usize + } +} + +struct SetUsize { + val: c_int, +} + +impl<'a> Set<'a, usize> for SetUsize { + fn new(val: &'a usize) -> SetUsize { + SetUsize { val: *val as c_int } + } + + unsafe fn ffi_ptr(&self) -> *const c_void { + mem::transmute(&self.val) + } + + unsafe fn ffi_len(&self) -> socklen_t { + mem::size_of::<c_int>() as socklen_t + } +} #[cfg(test)] mod test { |