|
@@ -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),
|