Add poll
This commit is contained in:
@@ -16,6 +16,7 @@ pub mod limits;
|
||||
pub mod locale;
|
||||
pub mod netdb;
|
||||
pub mod netinet_in;
|
||||
pub mod poll;
|
||||
//pub mod pthread;
|
||||
pub mod pwd;
|
||||
pub mod regex;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
sys_includes = []
|
||||
include_guard = "_POLL_H"
|
||||
language = "C"
|
||||
style = "Tag"
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
@@ -0,0 +1,22 @@
|
||||
//! poll implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/poll.h.html
|
||||
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
|
||||
pub const POLLIN: c_short = 0x001;
|
||||
pub const POLLPRI: c_short = 0x002;
|
||||
pub const POLLOUT: c_short = 0x004;
|
||||
|
||||
pub type nfds_t = c_ulong;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pollfd {
|
||||
pub fd: c_int,
|
||||
pub events: c_short,
|
||||
pub revents: c_short,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int {
|
||||
Sys::poll(fds, nfds, timeout)
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use core::ptr;
|
||||
|
||||
use c_str::CStr;
|
||||
use fs::File;
|
||||
use header::{errno, fcntl};
|
||||
use io::{BufRead, BufReader};
|
||||
@@ -56,10 +55,7 @@ where
|
||||
// TODO F: FnMut(impl Iterator<Item = &[u8]>) -> bool
|
||||
F: FnMut(&[&[u8]]) -> bool,
|
||||
{
|
||||
let file = match File::open(
|
||||
unsafe { CStr::from_bytes_with_nul_unchecked(b"/etc/passwd\0") },
|
||||
fcntl::O_RDONLY,
|
||||
) {
|
||||
let file = match File::open(c_str!("/etc/passwd"), fcntl::O_RDONLY) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return OptionPasswd::Error,
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#![feature(global_asm)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(linkage)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(thread_local)]
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use fs::File;
|
||||
use header::dirent::dirent;
|
||||
use header::errno::EINVAL;
|
||||
use header::fcntl;
|
||||
use header::poll::{nfds_t, pollfd};
|
||||
use header::signal::SIGCHLD;
|
||||
use header::sys_ioctl::{winsize, TCGETS, TCSETS, TIOCGWINSZ};
|
||||
// use header::sys_resource::rusage;
|
||||
@@ -296,6 +297,10 @@ impl Pal for Sys {
|
||||
e(unsafe { syscall!(PIPE2, fildes.as_mut_ptr(), 0) }) as c_int
|
||||
}
|
||||
|
||||
fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int {
|
||||
e(unsafe { syscall!(POLL, fds, nfds, timeout) }) as c_int
|
||||
}
|
||||
|
||||
fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t {
|
||||
e(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::types::*;
|
||||
use c_str::CStr;
|
||||
use header::dirent::dirent;
|
||||
use header::poll::{nfds_t, pollfd};
|
||||
use header::sys_select::fd_set;
|
||||
use header::sys_stat::stat;
|
||||
use header::sys_time::{timeval, timezone};
|
||||
@@ -110,6 +111,8 @@ pub trait Pal {
|
||||
|
||||
fn pipe(fildes: &mut [c_int]) -> c_int;
|
||||
|
||||
fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int;
|
||||
|
||||
fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t;
|
||||
|
||||
//fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t;
|
||||
@@ -120,6 +123,7 @@ pub trait Pal {
|
||||
|
||||
fn rmdir(path: &CStr) -> c_int;
|
||||
|
||||
//TODO: Deprecate in favor of poll
|
||||
fn select(
|
||||
nfds: c_int,
|
||||
readfds: *mut fd_set,
|
||||
|
||||
+128
-5
@@ -15,9 +15,7 @@ use fs::File;
|
||||
use header::dirent::dirent;
|
||||
use header::errno::{EINVAL, EIO, EPERM};
|
||||
use header::fcntl;
|
||||
use io::prelude::*;
|
||||
use io::{self, BufReader, SeekFrom};
|
||||
const MAP_ANON: c_int = 1;
|
||||
use header::poll::{self, nfds_t, pollfd};
|
||||
use header::sys_select::fd_set;
|
||||
use header::sys_stat::stat;
|
||||
use header::sys_time::{timeval, timezone};
|
||||
@@ -25,6 +23,8 @@ use header::sys_utsname::{utsname, UTSLENGTH};
|
||||
use header::termios::termios;
|
||||
use header::time::timespec;
|
||||
use header::unistd::{F_OK, R_OK, SEEK_SET, W_OK, X_OK};
|
||||
use io::prelude::*;
|
||||
use io::{self, BufReader, SeekFrom};
|
||||
|
||||
use super::types::*;
|
||||
use super::{errno, Pal, Read};
|
||||
@@ -32,6 +32,8 @@ use super::{errno, Pal, Read};
|
||||
mod signal;
|
||||
mod socket;
|
||||
|
||||
const MAP_ANON: c_int = 1;
|
||||
|
||||
static ANONYMOUS_MAPS: Once<Mutex<BTreeMap<usize, usize>>> = Once::new();
|
||||
|
||||
fn anonymous_maps() -> MutexGuard<'static, BTreeMap<usize, usize>> {
|
||||
@@ -705,6 +707,127 @@ 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;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
fn read(fd: c_int, buf: &mut [u8]) -> ssize_t {
|
||||
e(syscall::read(fd as usize, buf)) as ssize_t
|
||||
}
|
||||
@@ -756,7 +879,7 @@ impl Pal for Sys {
|
||||
let mut exceptfds =
|
||||
unsafe { exceptfds.as_mut() }.map(|s| BitSet::from_ref(&mut s.fds_bits));
|
||||
|
||||
let event_path = unsafe { CStr::from_bytes_with_nul_unchecked(b"event:\0") };
|
||||
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,
|
||||
@@ -933,7 +1056,7 @@ impl Pal for Sys {
|
||||
|
||||
fn uname(utsname: *mut utsname) -> c_int {
|
||||
fn inner(utsname: *mut utsname) -> CoreResult<(), i32> {
|
||||
let file_path = unsafe { CStr::from_bytes_with_nul_unchecked(b"sys:uname\0") };
|
||||
let file_path = c_str!("sys:uname\0");
|
||||
let mut file = match File::open(file_path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return Err(EIO),
|
||||
|
||||
Reference in New Issue
Block a user