0.3.0: converge relibc to upstream 0.6.0 + Red Bear patches
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
sys_includes = []
|
||||
sys_includes = ["signal.h"]
|
||||
include_guard = "_RELIBC_POLL_H"
|
||||
after_includes = """
|
||||
#include <bits/timespec.h> // for timespec
|
||||
"""
|
||||
language = "C"
|
||||
style = "Tag"
|
||||
no_includes = true
|
||||
no_includes = false
|
||||
cpp_compat = true
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
|
||||
[export.rename]
|
||||
"timespec" = "struct timespec"
|
||||
|
||||
+102
-17
@@ -1,14 +1,25 @@
|
||||
//! poll implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/poll.h.html
|
||||
//! `poll.h` implementation.
|
||||
//!
|
||||
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/poll.h.html>.
|
||||
|
||||
use core::{mem, slice};
|
||||
use core::{mem, ptr, slice};
|
||||
|
||||
use crate::{
|
||||
fs::File,
|
||||
header::sys_epoll::{
|
||||
epoll_create1, epoll_ctl, epoll_data, epoll_event, epoll_wait, EPOLLERR, EPOLLHUP, EPOLLIN,
|
||||
EPOLLNVAL, EPOLLOUT, EPOLLPRI, EPOLL_CLOEXEC, EPOLL_CTL_ADD,
|
||||
header::{
|
||||
bits_sigset_t::sigset_t,
|
||||
bits_timespec::timespec,
|
||||
errno::EBADF,
|
||||
sys_epoll::{
|
||||
EPOLL_CLOEXEC, EPOLL_CTL_ADD, EPOLLERR, EPOLLHUP, EPOLLIN, EPOLLNVAL, EPOLLOUT,
|
||||
EPOLLPRI, EPOLLRDBAND, EPOLLRDNORM, EPOLLWRBAND, EPOLLWRNORM, epoll_create1, epoll_ctl,
|
||||
epoll_data, epoll_event, epoll_pwait,
|
||||
},
|
||||
},
|
||||
platform::{
|
||||
self,
|
||||
types::{c_int, c_short, c_ulong},
|
||||
},
|
||||
platform::types::*,
|
||||
};
|
||||
|
||||
pub const POLLIN: c_short = 0x001;
|
||||
@@ -17,9 +28,14 @@ pub const POLLOUT: c_short = 0x004;
|
||||
pub const POLLERR: c_short = 0x008;
|
||||
pub const POLLHUP: c_short = 0x010;
|
||||
pub const POLLNVAL: c_short = 0x020;
|
||||
pub const POLLRDNORM: c_short = 0x040;
|
||||
pub const POLLRDBAND: c_short = 0x080;
|
||||
pub const POLLWRNORM: c_short = 0x100;
|
||||
pub const POLLWRBAND: c_short = 0x200;
|
||||
|
||||
pub type nfds_t = c_ulong;
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/poll.h.html>.
|
||||
#[repr(C)]
|
||||
pub struct pollfd {
|
||||
pub fd: c_int,
|
||||
@@ -27,7 +43,7 @@ pub struct pollfd {
|
||||
pub revents: c_short,
|
||||
}
|
||||
|
||||
pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int {
|
||||
pub unsafe fn poll_epoll(fds: &mut [pollfd], timeout: c_int, sigmask: *const sigset_t) -> c_int {
|
||||
let event_map = [
|
||||
(POLLIN, EPOLLIN),
|
||||
(POLLPRI, EPOLLPRI),
|
||||
@@ -35,6 +51,10 @@ pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int {
|
||||
(POLLERR, EPOLLERR),
|
||||
(POLLHUP, EPOLLHUP),
|
||||
(POLLNVAL, EPOLLNVAL),
|
||||
(POLLRDNORM, EPOLLRDNORM),
|
||||
(POLLWRNORM, EPOLLWRNORM),
|
||||
(POLLRDBAND, EPOLLRDBAND),
|
||||
(POLLWRBAND, EPOLLWRBAND),
|
||||
];
|
||||
|
||||
let ep = {
|
||||
@@ -45,8 +65,16 @@ pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int {
|
||||
File::new(epfd)
|
||||
};
|
||||
|
||||
for i in 0..fds.len() {
|
||||
let mut pfd = &mut fds[i];
|
||||
let mut closed = 0;
|
||||
for (i, fd) in fds.iter_mut().enumerate() {
|
||||
let pfd = fd;
|
||||
|
||||
pfd.revents = 0;
|
||||
|
||||
// Ignore the entry with negative fd
|
||||
if pfd.fd < 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut event = epoll_event {
|
||||
events: 0,
|
||||
@@ -60,15 +88,31 @@ pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int {
|
||||
}
|
||||
}
|
||||
|
||||
pfd.revents = 0;
|
||||
|
||||
if epoll_ctl(*ep, EPOLL_CTL_ADD, pfd.fd, &mut event) < 0 {
|
||||
return -1;
|
||||
if unsafe { epoll_ctl(*ep, EPOLL_CTL_ADD, pfd.fd, &raw mut event) } < 0 {
|
||||
if platform::ERRNO.get() == EBADF {
|
||||
pfd.revents |= POLLNVAL;
|
||||
closed += 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Early exit if there are fds, and all are closed (revents = POLLNVAL)
|
||||
if closed > 0 && closed == fds.len() {
|
||||
return closed as i32;
|
||||
}
|
||||
|
||||
let mut events: [epoll_event; 32] = unsafe { mem::zeroed() };
|
||||
let res = epoll_wait(*ep, events.as_mut_ptr(), events.len() as c_int, timeout);
|
||||
let res = unsafe {
|
||||
epoll_pwait(
|
||||
*ep,
|
||||
events.as_mut_ptr(),
|
||||
events.len() as c_int,
|
||||
timeout,
|
||||
sigmask,
|
||||
)
|
||||
};
|
||||
if res < 0 {
|
||||
return -1;
|
||||
}
|
||||
@@ -94,13 +138,54 @@ pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int {
|
||||
count
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/poll.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int {
|
||||
trace_expr!(
|
||||
poll_epoll(slice::from_raw_parts_mut(fds, nfds as usize), timeout),
|
||||
unsafe {
|
||||
poll_epoll(
|
||||
slice::from_raw_parts_mut(fds, nfds as usize),
|
||||
timeout,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
},
|
||||
"poll({:p}, {}, {})",
|
||||
fds,
|
||||
nfds,
|
||||
timeout
|
||||
timeout,
|
||||
)
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ppoll.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn ppoll(
|
||||
fds: *mut pollfd,
|
||||
nfds: nfds_t,
|
||||
tmo_p: *const timespec,
|
||||
sigmask: *const sigset_t,
|
||||
) -> c_int {
|
||||
let timeout = if tmo_p.is_null() {
|
||||
-1
|
||||
} else {
|
||||
let tmo = unsafe { &*tmo_p };
|
||||
if tmo.tv_sec > (c_int::MAX / 1000) as _ {
|
||||
c_int::MAX
|
||||
} else {
|
||||
((tmo.tv_sec as c_int) * 1000) + ((tmo.tv_nsec as c_int) / 1000000)
|
||||
}
|
||||
};
|
||||
trace_expr!(
|
||||
unsafe {
|
||||
poll_epoll(
|
||||
slice::from_raw_parts_mut(fds, nfds as usize),
|
||||
timeout,
|
||||
sigmask,
|
||||
)
|
||||
},
|
||||
"ppoll({:p}, {}, {:p}, {:p})",
|
||||
fds,
|
||||
nfds,
|
||||
tmo_p,
|
||||
sigmask
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user