diff options
Diffstat (limited to 'src/sys/event.rs')
-rw-r--r-- | src/sys/event.rs | 135 |
1 files changed, 129 insertions, 6 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; +} |