Bring in changes that were accidently lost
This commit is contained in:
@@ -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;
|
||||
|
||||
+16
-15
@@ -20,31 +20,32 @@ 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,
|
||||
pub u32: u32,
|
||||
pub u64: u64,
|
||||
}
|
||||
impl Default for epoll_data {
|
||||
fn default() -> Self {
|
||||
Self { u64: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
// This will match in size with syscall::Event (24 bytes on 64-bit
|
||||
// systems) on redox. The `Default` trait is here so we don't need to
|
||||
// worry about the padding when using this type.
|
||||
pub struct epoll_event {
|
||||
pub events: u32,
|
||||
pub data: epoll_data,
|
||||
pub events: u32, // 4 bytes
|
||||
// 4 automatic alignment bytes
|
||||
pub data: epoll_data, // 8 bytes
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub _pad: u64, // 8 bytes
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
use platform::types::*;
|
||||
|
||||
pub const EPOLL_CLOEXEC: c_int = 0x0100_0000;
|
||||
|
||||
pub const EPOLLIN: c_uint = 1;
|
||||
pub const EPOLLPRI: c_uint = 0;
|
||||
pub const EPOLLOUT: c_uint = 2;
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
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 {
|
||||
Sys::write(epfd, &Event {
|
||||
id: fd as usize,
|
||||
flags: unsafe { (*event).events as usize },
|
||||
|
||||
// NOTE: Danger when using non 64-bit systems. If this is
|
||||
// needed, use a box or something
|
||||
data: unsafe { mem::transmute((*event).data) }
|
||||
}) 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 _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(
|
||||
events as *mut u8,
|
||||
maxevents as usize
|
||||
) });
|
||||
if bytes_read == -1 {
|
||||
return -1;
|
||||
}
|
||||
let read = bytes_read as usize / mem::size_of::<Event>();
|
||||
|
||||
for i in 0..maxevents {
|
||||
unsafe {
|
||||
let event = *(events as *mut Event);
|
||||
if event.data == 0 {
|
||||
return EINTR;
|
||||
}
|
||||
*events = epoll_event {
|
||||
events: event.flags as _,
|
||||
data: mem::transmute(event.data),
|
||||
..Default::default()
|
||||
};
|
||||
events = events.add(mem::size_of::<epoll_event>());
|
||||
}
|
||||
}
|
||||
|
||||
read as c_int
|
||||
}
|
||||
}
|
||||
+2
-131
@@ -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;
|
||||
@@ -679,7 +679,7 @@ impl Pal for Sys {
|
||||
)) as c_int
|
||||
}
|
||||
|
||||
fn pipe(fds: &mut [c_int], flags: c_int) -> c_int {
|
||||
fn pipe2(fds: &mut [c_int], flags: c_int) -> c_int {
|
||||
let mut usize_fds: [usize; 2] = [0; 2];
|
||||
let res = e(syscall::pipe2(&mut usize_fds, flags as usize));
|
||||
fds[0] = usize_fds[0] as c_int;
|
||||
@@ -687,135 +687,6 @@ impl Pal for Sys {
|
||||
res as c_int
|
||||
}
|
||||
|
||||
fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int {
|
||||
let fds = unsafe { slice::from_raw_parts_mut(fds, nfds as usize) };
|
||||
|
||||
let event_path = c_str!("event:");
|
||||
let mut event_file = match File::open(event_path, fcntl::O_RDWR | fcntl::O_CLOEXEC) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
for fd in fds.iter_mut() {
|
||||
let mut flags = 0;
|
||||
|
||||
if fd.events & poll::POLLIN > 0 {
|
||||
flags |= syscall::EVENT_READ;
|
||||
}
|
||||
|
||||
if fd.events & poll::POLLOUT > 0 {
|
||||
flags |= syscall::EVENT_WRITE;
|
||||
}
|
||||
|
||||
fd.revents = 0;
|
||||
|
||||
if fd.fd >= 0 && flags > 0 {
|
||||
if event_file
|
||||
.write(&syscall::Event {
|
||||
id: fd.fd as usize,
|
||||
flags: flags,
|
||||
data: 0,
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const TIMEOUT_TOKEN: usize = 1;
|
||||
|
||||
let timeout_file = if timeout < 0 {
|
||||
None
|
||||
} else {
|
||||
let timeout_path = unsafe {
|
||||
CString::from_vec_unchecked(
|
||||
format!("time:{}", syscall::CLOCK_MONOTONIC).into_bytes(),
|
||||
)
|
||||
};
|
||||
let mut timeout_file = match File::open(&timeout_path, fcntl::O_RDWR | fcntl::O_CLOEXEC)
|
||||
{
|
||||
Ok(file) => file,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
if event_file
|
||||
.write(&syscall::Event {
|
||||
id: *timeout_file as usize,
|
||||
flags: syscall::EVENT_READ,
|
||||
data: TIMEOUT_TOKEN,
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
let mut time = syscall::TimeSpec::default();
|
||||
if timeout_file.read(&mut time).is_err() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
time.tv_nsec += timeout * 1000000;
|
||||
while time.tv_nsec >= 1000000000 {
|
||||
time.tv_sec += 1;
|
||||
time.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
// Teehee
|
||||
if timeout == 0 {
|
||||
time.tv_sec += 1;
|
||||
}
|
||||
|
||||
if timeout_file.write(&time).is_err() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Some(timeout_file)
|
||||
};
|
||||
|
||||
let mut events = [syscall::Event::default(); 32];
|
||||
let read = {
|
||||
let mut events = unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
&mut events as *mut _ as *mut u8,
|
||||
mem::size_of::<syscall::Event>() * events.len(),
|
||||
)
|
||||
};
|
||||
match event_file.read(&mut events) {
|
||||
Ok(i) => i / mem::size_of::<syscall::Event>(),
|
||||
Err(_) => return -1,
|
||||
}
|
||||
};
|
||||
|
||||
for event in &events[..read] {
|
||||
if event.data == TIMEOUT_TOKEN {
|
||||
continue;
|
||||
}
|
||||
|
||||
for fd in fds.iter_mut() {
|
||||
if event.id == fd.fd as usize {
|
||||
if event.flags & syscall::EVENT_READ > 0 {
|
||||
fd.revents |= poll::POLLIN;
|
||||
}
|
||||
|
||||
if event.flags & syscall::EVENT_WRITE > 0 {
|
||||
fd.revents |= poll::POLLOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut total = 0;
|
||||
|
||||
for fd in fds.iter_mut() {
|
||||
if fd.revents > 0 {
|
||||
total += 1;
|
||||
}
|
||||
}
|
||||
|
||||
total
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
unsafe fn pte_clone(stack: *mut usize) -> pid_t {
|
||||
let flags = syscall::CLONE_VM
|
||||
|
||||
Reference in New Issue
Block a user