Implement pselect and write test
This commit is contained in:
@@ -9,13 +9,15 @@ use cbitset::BitSet;
|
||||
use crate::{
|
||||
fs::File,
|
||||
header::{
|
||||
bits_sigset_t::sigset_t,
|
||||
errno,
|
||||
sys_epoll::{
|
||||
EPOLL_CLOEXEC, EPOLL_CTL_ADD, EPOLLERR, EPOLLIN, EPOLLOUT, epoll_create1, epoll_ctl,
|
||||
epoll_data, epoll_event, epoll_wait,
|
||||
epoll_data, epoll_event, epoll_pwait,
|
||||
},
|
||||
time::timespec,
|
||||
},
|
||||
platform::{self, types::c_int},
|
||||
platform::types::{c_int, suseconds_t},
|
||||
};
|
||||
|
||||
pub use crate::header::bits_timeval::timeval;
|
||||
@@ -42,9 +44,10 @@ pub fn select_epoll(
|
||||
writefds: Option<&mut fd_set>,
|
||||
exceptfds: Option<&mut fd_set>,
|
||||
timeout: Option<&mut timeval>,
|
||||
sigmask: *const sigset_t,
|
||||
) -> c_int {
|
||||
if nfds < 0 || nfds > FD_SETSIZE as i32 {
|
||||
platform::ERRNO.set(errno::EINVAL);
|
||||
crate::platform::ERRNO.set(errno::EINVAL);
|
||||
return -1;
|
||||
};
|
||||
|
||||
@@ -55,7 +58,6 @@ pub fn select_epoll(
|
||||
}
|
||||
File::new(epfd)
|
||||
};
|
||||
|
||||
let mut read_bitset: Option<&mut FdBitSet> = readfds.map(|fd_set| &mut fd_set.fds_bits);
|
||||
let mut write_bitset: Option<&mut FdBitSet> = writefds.map(|fd_set| &mut fd_set.fds_bits);
|
||||
let mut except_bitset: Option<&mut FdBitSet> = exceptfds.map(|fd_set| &mut fd_set.fds_bits);
|
||||
@@ -90,7 +92,7 @@ pub fn select_epoll(
|
||||
..Default::default() // clippy lint, _pad field on redox but not linux
|
||||
};
|
||||
if unsafe { epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &raw mut event) } < 0 {
|
||||
if platform::ERRNO.get() == errno::EPERM {
|
||||
if crate::platform::ERRNO.get() == errno::EPERM {
|
||||
not_epoll += 1;
|
||||
} else {
|
||||
return -1;
|
||||
@@ -134,12 +136,14 @@ pub fn select_epoll(
|
||||
None => -1,
|
||||
}
|
||||
};
|
||||
|
||||
let res = unsafe {
|
||||
epoll_wait(
|
||||
epoll_pwait(
|
||||
*ep,
|
||||
events.as_mut_ptr(),
|
||||
events.len() as c_int,
|
||||
epoll_timeout,
|
||||
sigmask,
|
||||
)
|
||||
};
|
||||
if res < 0 {
|
||||
@@ -174,7 +178,7 @@ pub fn select_epoll(
|
||||
count
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pselect.html>.
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/select.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn select(
|
||||
nfds: c_int,
|
||||
@@ -205,7 +209,8 @@ pub unsafe extern "C" fn select(
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &mut *timeout })
|
||||
}
|
||||
},
|
||||
core::ptr::null(),
|
||||
),
|
||||
"select({}, {:p}, {:p}, {:p}, {:p})",
|
||||
nfds,
|
||||
@@ -215,3 +220,54 @@ pub unsafe extern "C" fn select(
|
||||
timeout
|
||||
)
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pselect.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn pselect(
|
||||
nfds: c_int,
|
||||
readfds: *mut fd_set,
|
||||
writefds: *mut fd_set,
|
||||
exceptfds: *mut fd_set,
|
||||
timeout: *const timespec,
|
||||
sigmask: *const sigset_t,
|
||||
) -> c_int {
|
||||
let mut micro_timeout = if timeout.is_null() {
|
||||
None
|
||||
} else {
|
||||
unsafe {
|
||||
Some(timeval {
|
||||
tv_sec: (*timeout).tv_sec,
|
||||
tv_usec: ((*timeout).tv_nsec / 1000) as suseconds_t,
|
||||
})
|
||||
}
|
||||
};
|
||||
trace_expr!(
|
||||
select_epoll(
|
||||
nfds,
|
||||
if readfds.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &mut *readfds })
|
||||
},
|
||||
if writefds.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &mut *writefds })
|
||||
},
|
||||
if exceptfds.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &mut *exceptfds })
|
||||
},
|
||||
micro_timeout.as_mut(),
|
||||
sigmask
|
||||
),
|
||||
"pselect({}, {:p}, {:p}, {:p}, {:p}, {:p})",
|
||||
nfds,
|
||||
readfds,
|
||||
writefds,
|
||||
exceptfds,
|
||||
timeout,
|
||||
sigmask,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user