diff --git a/src/header/sys_epoll/linux.rs b/src/header/sys_epoll/linux.rs index af4972e7006f0365147d6c408ae6a27e53c3ebf7..654d4ff5cea04ac946b47da3ca6485f0d4ac5d9c 100644 --- a/src/header/sys_epoll/linux.rs +++ b/src/header/sys_epoll/linux.rs @@ -1,3 +1,20 @@ use platform::types::*; pub const EPOLL_CLOEXEC: c_int = 0x8_0000; + +pub const EPOLLIN: c_uint = 0x001; +pub const EPOLLPRI: c_uint = 0x002; +pub const EPOLLOUT: c_uint = 0x004; +pub const EPOLLRDNORM: c_uint = 0x040; +pub const EPOLLNVAL: c_uint = 0x020; +pub const EPOLLRDBAND: c_uint = 0x080; +pub const EPOLLWRNORM: c_uint = 0x100; +pub const EPOLLWRBAND: c_uint = 0x200; +pub const EPOLLMSG: c_uint = 0x400; +pub const EPOLLERR: c_uint = 0x008; +pub const EPOLLHUP: c_uint = 0x010; +pub const EPOLLRDHUP: c_uint = 0x2000; +pub const EPOLLEXCLUSIVE: c_uint = 1 << 28; +pub const EPOLLWAKEUP: c_uint = 1 << 29; +pub const EPOLLONESHOT: c_uint = 1 << 30; +pub const EPOLLET: c_uint = 1 << 31; diff --git a/src/header/sys_epoll/mod.rs b/src/header/sys_epoll/mod.rs index 06893bc0aa45d61fee2ebfe8ed7bf0b852fa85d3..ab8e4fc0d15cb6d3cf8b04907980a3fd162aa08c 100644 --- a/src/header/sys_epoll/mod.rs +++ b/src/header/sys_epoll/mod.rs @@ -20,20 +20,8 @@ pub const EPOLL_CTL_ADD: c_int = 1; pub const EPOLL_CTL_DEL: c_int = 2; pub const EPOLL_CTL_MOD: c_int = 3; -pub const EPOLLIN: u32 = 0x0001; -pub const EPOLLPRI: u32 = 0x0002; -pub const EPOLLOUT: u32 = 0x0004; -pub const EPOLLERR: u32 = 0x0008; -pub const EPOLLHUP: u32 = 0x0010; -pub const EPOLLNVAL: u32 = 0x0020; -pub const EPOLLRDNORM: u32 = 0x0040; -pub const EPOLLRDBAND: u32 = 0x0080; -pub const EPOLLWRNORM: u32 = 0x0100; -pub const EPOLLWRBAND: u32 = 0x0200; -pub const EPOLLMSG: u32 = 0x0400; -pub const EPOLLRDHUP: u32 = 0x2000; - #[repr(C)] +#[derive(Clone, Copy)] pub union epoll_data { pub ptr: *mut c_void, pub fd: c_int, @@ -42,6 +30,7 @@ pub union epoll_data { } #[repr(C)] +#[derive(Clone, Copy)] pub struct epoll_event { pub events: u32, pub data: epoll_data, diff --git a/src/header/sys_epoll/redox.rs b/src/header/sys_epoll/redox.rs index 870f7f9d9f9c4864ca6fb158276313c8397c8bb7..3a89259baa89163e43e2fff83bf529ee894a3afc 100644 --- a/src/header/sys_epoll/redox.rs +++ b/src/header/sys_epoll/redox.rs @@ -1,3 +1,22 @@ +use syscall::flag::{EVENT_READ, EVENT_WRITE}; +use header::fcntl::O_CLOEXEC; use platform::types::*; -pub const EPOLL_CLOEXEC: c_int = 0x0100_0000; +pub const EPOLL_CLOEXEC: c_int = O_CLOEXEC; + +pub const EPOLLIN: c_uint = EVENT_READ as c_uint; +pub const EPOLLPRI: c_uint = 0; +pub const EPOLLOUT: c_uint = EVENT_WRITE as c_uint; +pub const EPOLLRDNORM: c_uint = 0; +pub const EPOLLNVAL: c_uint = 0; +pub const EPOLLRDBAND: c_uint = 0; +pub const EPOLLWRNORM: c_uint = 0; +pub const EPOLLWRBAND: c_uint = 0; +pub const EPOLLMSG: c_uint = 0; +pub const EPOLLERR: c_uint = 0; +pub const EPOLLHUP: c_uint = 0; +pub const EPOLLRDHUP: c_uint = 0; +pub const EPOLLEXCLUSIVE: c_uint = 0; +pub const EPOLLWAKEUP: c_uint = 0; +pub const EPOLLONESHOT: c_uint = 0; +pub const EPOLLET: c_uint = 0; diff --git a/src/platform/redox/epoll.rs b/src/platform/redox/epoll.rs new file mode 100644 index 0000000000000000000000000000000000000000..c266e46352792925d907d34ed01a3f9a700423fc --- /dev/null +++ b/src/platform/redox/epoll.rs @@ -0,0 +1,86 @@ +use super::super::types::*; +use super::super::{Pal, PalEpoll}; +use super::Sys; + +use c_str::CStr; +use core::{mem, slice}; +use fs::File; +use io::prelude::*; +use header::errno::*; +use header::fcntl::*; +use header::signal::sigset_t; +use header::sys_epoll::*; +use syscall::data::{Event, TimeSpec}; +use syscall::flag::EVENT_READ; + +impl PalEpoll for Sys { + fn epoll_create1(flags: c_int) -> c_int { + Sys::open( + CStr::from_bytes_with_nul(b"event:\0").unwrap(), + O_RDWR | flags, + 0 + ) + } + + fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int { + let flags = unsafe { (*event).events }; + Sys::write(epfd, &Event { + id: fd as usize, + flags: flags as usize, + data: event as usize + }) as c_int + } + + fn epoll_pwait(epfd: c_int, mut events: *mut epoll_event, maxevents: c_int, timeout: c_int, _sigset: *const sigset_t) -> c_int { + // TODO: sigset + + let mut redox_events = vec![Event::default(); maxevents as usize]; + + let _timer; + if timeout != -1 { + _timer = File::open(CStr::from_bytes_with_nul(b"time:\0").unwrap(), O_RDWR); + match _timer { + Err(_) => return -1, + Ok(mut timer) => { + let mut time = TimeSpec::default(); + if let Err(err) = timer.read(&mut time) { + return -1; + } + time.tv_nsec += timeout; + if let Err(err) = timer.write(&time) { + return -1; + } + + if Sys::write(epfd, &Event { + id: timer.fd as usize, + flags: EVENT_READ, + data: 0 + }) == -1 { + return -1; + } + } + } + } + + let bytes_read = Sys::read(epfd, unsafe { slice::from_raw_parts_mut( + redox_events.as_mut_ptr() as *mut u8, + redox_events.len() * mem::size_of::<Event>() + ) }); + if bytes_read == -1 { + return -1; + } + let read = bytes_read as usize / mem::size_of::<Event>(); + + for event in &redox_events { + if event.data == 0 { + return EINTR; + } + unsafe { + *events = *(event.data as *mut epoll_event); + events = events.add(mem::size_of::<epoll_event>()); + } + } + + read as c_int + } +} diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 41d4b6e4dc086a10cdbcea301a1f6806da838826..603761c07afb7208fe5c91aee56d62128761541a 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -1,6 +1,5 @@ //! sys/socket implementation, following http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/socket.h.html -use cbitset::BitSet; use core::result::Result as CoreResult; use core::{mem, ptr, slice}; use syscall::data::Map; @@ -27,6 +26,7 @@ use io::{self, BufReader, SeekFrom}; use super::types::*; use super::{errno, Pal, Read}; +mod epoll; mod extra; mod signal; mod socket;