#[macro_use] extern crate bitflags;
extern crate libc;
use std::io::{self, Error};
use std::os::unix::io::RawFd;
bitflags! {
pub flags ControlOptions: i32 {
const EPOLL_CTL_ADD = libc::EPOLL_CTL_ADD,
const EPOLL_CTL_MOD = libc::EPOLL_CTL_MOD,
const EPOLL_CTL_DEL = libc::EPOLL_CTL_DEL
}
}
bitflags! {
pub flags Events: u32 {
const EPOLLET = libc::EPOLLET as u32,
const EPOLLIN = libc::EPOLLIN as u32,
const EPOLLERR = libc::EPOLLERR as u32,
const EPOLLHUP = libc::EPOLLHUP as u32,
const EPOLLOUT = libc::EPOLLOUT as u32,
const EPOLLPRI = libc::EPOLLPRI as u32,
const EPOLLRDHUP = libc::EPOLLRDHUP as u32,
const EPOLLWAKEUP = libc::EPOLLWAKEUP as u32,
const EPOLLONESHOT = libc::EPOLLONESHOT as u32
}
}
#[repr(C)]
#[repr(packed)]
#[derive(Clone, Copy)]
pub struct Event {
events: u32,
data: u64
}
impl Event {
pub fn new(events: Events, data: u64) -> Event {
Event { events: events.bits(), data: data }
}
}
pub fn create(cloexec: bool) -> io::Result<RawFd> {
let epfd = unsafe {
let fd = try!(cvt(libc::epoll_create(1)));
if cloexec {
let mut flags = try!(cvt(libc::fcntl(fd, libc::F_GETFD)));
flags |= libc::FD_CLOEXEC;
try!(cvt(libc::fcntl(fd, libc::F_SETFD, flags)));
}
fd
};
Ok(epfd)
}
pub fn ctl(epfd: RawFd,
op: ControlOptions,
fd: RawFd,
mut event: Event)
-> io::Result<()>
{
let e = &mut event as *mut _ as *mut libc::epoll_event;
unsafe { try!(cvt(libc::epoll_ctl(epfd, op.bits, fd, e))) };
Ok(())
}
pub fn wait(epfd: RawFd,
timeout: i32,
buf: &mut [Event])
-> io::Result<usize>
{
let timeout = if timeout < -1 { -1 } else { timeout };
let num_events = unsafe {
try!(cvt(libc::epoll_wait(epfd,
buf.as_mut_ptr() as *mut libc::epoll_event,
buf.len() as i32,
timeout))) as usize
};
Ok(num_events)
}
fn cvt(result: libc::c_int) -> io::Result<libc::c_int> {
if result < 0 { Err(Error::last_os_error()) } else { Ok(result) }
}