diff options
author | Zachary Tong <zacharyjtong@gmail.com> | 2015-11-22 08:04:41 -0500 |
---|---|---|
committer | Carl Lerche <me@carllerche.com> | 2015-12-03 13:15:20 -0800 |
commit | 1b97d964ece80f9fff9adad721dbaffe92d90a07 (patch) | |
tree | ef2153ca553e9ffb49606cf340fcbeb84ed03fb6 /src | |
parent | 04d315dee956ed8223cbac2be0839d0dae9497a5 (diff) | |
download | nix-1b97d964ece80f9fff9adad721dbaffe92d90a07.zip |
NetBSD tweaks for kqueue support
Diffstat (limited to 'src')
-rw-r--r-- | src/sys/event.rs | 135 | ||||
-rw-r--r-- | src/sys/mod.rs | 3 | ||||
-rw-r--r-- | src/sys/socket/consts.rs | 8 | ||||
-rw-r--r-- | src/sys/socket/sockopt.rs | 4 |
4 files changed, 142 insertions, 8 deletions
diff --git a/src/sys/event.rs b/src/sys/event.rs index d95b2107..6498cb97 100644 --- a/src/sys/event.rs +++ b/src/sys/event.rs @@ -3,16 +3,20 @@ use {Error, Result}; use errno::Errno; +#[cfg(not(target_os = "netbsd"))] use libc::{timespec, time_t, c_int, c_long, uintptr_t}; +#[cfg(target_os = "netbsd")] +use libc::{timespec, time_t, c_long, uintptr_t, size_t}; use std::os::unix::io::RawFd; use std::ptr; pub use self::ffi::kevent as KEvent; mod ffi { - pub use libc::{c_int, c_void, uintptr_t, intptr_t, timespec}; + pub use libc::{c_int, c_void, uintptr_t, intptr_t, timespec, size_t, int64_t}; use super::{EventFilter, EventFlag, FilterFlag}; + #[cfg(not(target_os = "netbsd"))] #[derive(Clone, Copy)] #[repr(C)] pub struct kevent { @@ -24,11 +28,24 @@ mod ffi { pub udata: usize // 8 } + #[cfg(target_os = "netbsd")] + #[derive(Clone, Copy)] + #[repr(C)] + pub struct kevent { + pub ident: uintptr_t, + pub filter: EventFilter, + pub flags: EventFlag, + pub fflags: FilterFlag, + pub data: int64_t, + pub udata: intptr_t + } + // Bug in rustc, cannot determine that kevent is #[repr(C)] #[allow(improper_ctypes)] extern { pub fn kqueue() -> c_int; + #[cfg(not(target_os = "netbsd"))] pub fn kevent( kq: c_int, changelist: *const kevent, @@ -36,10 +53,19 @@ mod ffi { eventlist: *mut kevent, nevents: c_int, timeout: *const timespec) -> c_int; + + #[cfg(target_os = "netbsd")] + pub fn kevent( + kq: c_int, + changelist: *const kevent, + nchanges: size_t, + eventlist: *mut kevent, + nevents: size_t, + timeout: *const timespec) -> c_int; } } -#[cfg(not(target_os = "dragonfly"))] +#[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] #[repr(i16)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum EventFilter { @@ -73,7 +99,21 @@ pub enum EventFilter { EVFILT_USER = -9, } -#[cfg(not(target_os = "dragonfly"))] +#[cfg(target_os = "netbsd")] +#[repr(u32)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum EventFilter { + EVFILT_READ = 0, + EVFILT_WRITE = 1, + EVFILT_AIO = 2, + EVFILT_VNODE = 3, + EVFILT_PROC = 4, + EVFILT_SIGNAL = 5, + EVFILT_TIMER = 6, + EVFILT_SYSCOUNT = 7 +} + +#[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] bitflags!( flags EventFlag: u16 { const EV_ADD = 0x0001, @@ -110,7 +150,24 @@ bitflags!( } ); -#[cfg(not(target_os = "dragonfly"))] +#[cfg(target_os = "netbsd")] +bitflags!( + flags EventFlag: u32 { + const EV_ADD = 0x0001, + const EV_DELETE = 0x0002, + const EV_ENABLE = 0x0004, + const EV_DISABLE = 0x0008, + const EV_ONESHOT = 0x0010, + const EV_CLEAR = 0x0020, + const EV_SYSFLAGS = 0xF000, + const EV_NODATA = 0x1000, + const EV_FLAG1 = 0x2000, + const EV_EOF = 0x8000, + const EV_ERROR = 0x4000 + } +); + +#[cfg(not(any(target_os = "dragonfly", target_os="netbsd")))] bitflags!( flags FilterFlag: u32 { const NOTE_TRIGGER = 0x01000000, @@ -188,10 +245,33 @@ bitflags!( } ); -#[cfg(not(target_os = "dragonfly"))] +#[cfg(target_os = "netbsd")] +bitflags!( + flags FilterFlag: u32 { + const NOTE_LOWAT = 0x00000001, + const NOTE_DELETE = 0x00000001, + const NOTE_WRITE = 0x00000002, + const NOTE_EXTEND = 0x00000004, + const NOTE_ATTRIB = 0x00000008, + const NOTE_LINK = 0x00000010, + const NOTE_RENAME = 0x00000020, + const NOTE_REVOKE = 0x00000040, + const NOTE_EXIT = 0x80000000, + const NOTE_FORK = 0x40000000, + const NOTE_EXEC = 0x20000000, + const NOTE_SIGNAL = 0x08000000, + const NOTE_PDATAMASK = 0x000fffff, + const NOTE_PCTRLMASK = 0xf0000000, // NOTE: FreeBSD uses 0xfff00000, + const NOTE_TRACK = 0x00000001, + const NOTE_TRACKERR = 0x00000002, + const NOTE_CHILD = 0x00000004 + } +); + +#[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] pub const EV_POLL: EventFlag = EV_FLAG0; -#[cfg(not(target_os = "dragonfly"))] +#[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] pub const EV_OOBAND: EventFlag = EV_FLAG1; pub fn kqueue() -> Result<RawFd> { @@ -218,10 +298,12 @@ pub fn kevent(kq: RawFd, kevent_ts(kq, changelist, eventlist, Some(timeout)) } +#[cfg(not(target_os = "netbsd"))] pub fn kevent_ts(kq: RawFd, changelist: &[KEvent], eventlist: &mut [KEvent], timeout_opt: Option<timespec>) -> Result<usize> { + let res = unsafe { ffi::kevent( kq, @@ -239,6 +321,30 @@ pub fn kevent_ts(kq: RawFd, return Ok(res as usize) } +#[cfg(target_os = "netbsd")] +pub fn kevent_ts(kq: RawFd, + changelist: &[KEvent], + eventlist: &mut [KEvent], + timeout_opt: Option<timespec>) -> Result<usize> { + + let res = unsafe { + ffi::kevent( + kq, + changelist.as_ptr(), + changelist.len() as size_t, + eventlist.as_mut_ptr(), + eventlist.len() as size_t, + if let Some(ref timeout) = timeout_opt {timeout as *const timespec} else {ptr::null()}) + }; + + if res < 0 { + return Err(Error::Sys(Errno::last())); + } + + return Ok(res as usize) +} + +#[cfg(not(target_os = "netbsd"))] #[inline] pub fn ev_set(ev: &mut KEvent, ident: usize, @@ -254,3 +360,20 @@ pub fn ev_set(ev: &mut KEvent, ev.data = 0; ev.udata = udata; } + +#[cfg(target_os = "netbsd")] +#[inline] +pub fn ev_set(ev: &mut KEvent, + ident: usize, + filter: EventFilter, + flags: EventFlag, + fflags: FilterFlag, + udata: i64) { + + ev.ident = ident as uintptr_t; + ev.filter = filter; + ev.flags = flags; + ev.fflags = fflags; + ev.data = 0; + ev.udata = udata; +} diff --git a/src/sys/mod.rs b/src/sys/mod.rs index 6e40c57f..c7fdc4dc 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -2,7 +2,8 @@ #[cfg(any(target_os = "linux", target_os = "android"))] pub mod epoll; -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd", + target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd"))] pub mod event; // TODO: switch from feature flags to conditional builds diff --git a/src/sys/socket/consts.rs b/src/sys/socket/consts.rs index 22bd02a2..ef8c23f6 100644 --- a/src/sys/socket/consts.rs +++ b/src/sys/socket/consts.rs @@ -208,7 +208,13 @@ mod os { pub const IPV6_ADD_MEMBERSHIP: c_int = libc::IPV6_ADD_MEMBERSHIP; #[cfg(not(target_os = "netbsd"))] pub const IPV6_DROP_MEMBERSHIP: c_int = libc::IPV6_DROP_MEMBERSHIP; - + + #[cfg(target_os = "netbsd")] + pub const IPV6_JOIN_GROUP: c_int = 12; + + #[cfg(target_os = "netbsd")] + pub const IPV6_LEAVE_GROUP: c_int = 13; + pub type InAddrT = u32; // Declarations of special addresses diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index ede9d408..2f01b91d 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -125,6 +125,10 @@ sockopt_impl!(SetOnly, IpDropMembership, consts::IPPROTO_IP, consts::IP_DROP_MEM sockopt_impl!(SetOnly, Ipv6AddMembership, consts::IPPROTO_IPV6, consts::IPV6_ADD_MEMBERSHIP, super::ipv6_mreq); #[cfg(not(target_os = "netbsd"))] sockopt_impl!(SetOnly, Ipv6DropMembership, consts::IPPROTO_IPV6, consts::IPV6_DROP_MEMBERSHIP, super::ipv6_mreq); +#[cfg(target_os = "netbsd")] +sockopt_impl!(SetOnly, Ipv6AddMembership, consts::IPPROTO_IPV6, consts::IPV6_JOIN_GROUP, super::ipv6_mreq); +#[cfg(target_os = "netbsd")] +sockopt_impl!(SetOnly, Ipv6DropMembership, consts::IPPROTO_IPV6, consts::IPV6_LEAVE_GROUP, super::ipv6_mreq); sockopt_impl!(Both, IpMulticastTtl, consts::IPPROTO_IP, consts::IP_MULTICAST_TTL, u8); sockopt_impl!(Both, IpMulticastLoop, consts::IPPROTO_IP, consts::IP_MULTICAST_LOOP, bool); sockopt_impl!(Both, ReceiveTimeout, consts::SOL_SOCKET, consts::SO_RCVTIMEO, TimeVal); |