extern crate libc;
extern crate errno;
use std::result::Result;
use std::os::unix::io::RawFd;
use errno::errno;
use libc::c_int;
use libc::consts::os::posix88;
use util::*;
pub mod util;
pub type CreateResult = Result<RawFd, CreateError>;
pub type CtlResult = Result<(), CtlError>;
pub type WaitResult = Result<u32, WaitError>;
#[cfg(target_arch = "x86_64")]
#[repr(C, packed)]
pub struct EpollEvent {
pub events: u32,
pub data: u64
}
#[cfg(not(target_arch = "x86_64"))]
#[repr(C)]
pub struct EpollEvent {
pub events: u32,
pub data: u64
}
extern "C" {
fn epoll_create1(flags: c_int) -> c_int;
fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int,
event: *mut EpollEvent) -> c_int;
fn epoll_wait(epfd: c_int, event: *mut EpollEvent,
maxevents: c_int, timeout: c_int) -> c_int;
}
#[inline]
pub fn create1(flags: u32) -> CreateResult {
let mut epoll_fd;
unsafe {
epoll_fd = epoll_create1(flags as c_int);
}
if epoll_fd == -1 {
let errno = errno().0 as i32;
return match errno {
posix88::EINVAL => Err(CreateError::EINVAL),
posix88::EMFILE => Err(CreateError::EMFILE),
posix88::ENFILE => Err(CreateError::ENFILE),
posix88::ENOMEM => Err(CreateError::ENOMEM),
_ => panic!("Unexpected errno: {}", errno)
}
}
Ok(epoll_fd)
}
#[inline]
pub fn ctl(epoll_fd: RawFd, op: u32,
socket_fd: RawFd, event: &mut EpollEvent) -> CtlResult {
let mut x;
unsafe {
x = epoll_ctl(epoll_fd as c_int,
op as c_int,
socket_fd as c_int,
event as *mut EpollEvent);
}
if x == -1 {
let errno = errno().0 as i32;
return match errno {
posix88::EBADF => Err(CtlError::EBADF),
posix88::EEXIST => Err(CtlError::EEXIST),
posix88::EINVAL => Err(CtlError::EINVAL),
posix88::ENOENT => Err(CtlError::ENOENT),
posix88::ENOSPC => Err(CtlError::ENOSPC),
posix88::EPERM => Err(CtlError::EPERM),
_ => panic!("Unexpected errno: {}", errno)
}
}
Ok(())
}
#[inline]
pub fn wait(epoll_fd: RawFd, events: &mut [EpollEvent],
timeout: i32) -> WaitResult {
let mut num_fds_ready;
unsafe {
num_fds_ready = epoll_wait(epoll_fd as c_int,
events.as_mut_ptr(),
events.len() as c_int,
timeout as c_int);
}
if num_fds_ready == -1 {
let errno = errno().0 as i32;
return match errno {
posix88::EBADF => Err(WaitError::EBADF),
posix88::EFAULT => Err(WaitError::EFAULT),
posix88::EINTR => Err(WaitError::EINTR),
posix88::EINVAL => Err(WaitError::EINVAL),
_ => panic!("Unexpected errno: {}", errno)
}
}
Ok(num_fds_ready as u32)
}