feature: simple select()
This commit is contained in:
@@ -15,3 +15,4 @@ pub const SYS_FORK: usize = 7;
|
||||
pub const SYS_EXECVE: usize = 8;
|
||||
pub const SYS_WAITPID: usize = 9;
|
||||
pub const SYS_IOCTL: usize = 10;
|
||||
pub const SYS_SELECT: usize = 11;
|
||||
|
||||
+17
-1
@@ -2,7 +2,7 @@ use crate::abi;
|
||||
use crate::{
|
||||
ioctl::IoctlCmd,
|
||||
signal::Signal,
|
||||
stat::{FileMode, OpenFlags, Stat},
|
||||
stat::{FdSet, FileMode, OpenFlags, Stat},
|
||||
};
|
||||
|
||||
// TODO document the syscall ABI
|
||||
@@ -217,3 +217,19 @@ pub unsafe fn sys_ex_sigreturn() -> ! {
|
||||
pub unsafe fn sys_ex_kill(pid: u32, signum: Signal) -> i32 {
|
||||
syscall!(abi::SYS_EX_KILL, argn!(pid), argn!(signum as u32)) as i32
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_select(
|
||||
n: u32,
|
||||
read_fds: Option<&mut FdSet>,
|
||||
write_fds: Option<&mut FdSet>,
|
||||
timeout: u64,
|
||||
) -> i32 {
|
||||
syscall!(
|
||||
abi::SYS_SELECT,
|
||||
argn!(n),
|
||||
argp!(read_fds.map(|e| e as *mut _).unwrap_or(core::ptr::null_mut())),
|
||||
argp!(write_fds.map(|e| e as *mut _).unwrap_or(core::ptr::null_mut())),
|
||||
argn!(timeout)
|
||||
) as i32
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use core::fmt;
|
||||
|
||||
pub const AT_FDCWD: i32 = -2;
|
||||
pub const AT_EMPTY_PATH: u32 = 1 << 16;
|
||||
|
||||
@@ -32,6 +34,16 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct FdSet {
|
||||
bits: [u64; 2]
|
||||
}
|
||||
|
||||
struct FdSetIter<'a> {
|
||||
idx: u32,
|
||||
set: &'a FdSet
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[repr(C)]
|
||||
pub struct Stat {
|
||||
@@ -40,6 +52,75 @@ pub struct Stat {
|
||||
pub blksize: u32,
|
||||
}
|
||||
|
||||
impl FdSet {
|
||||
pub const fn empty() -> Self {
|
||||
Self { bits: [0; 2] }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reset(&mut self) {
|
||||
self.bits.fill(0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.bits.iter().find(|&&x| x != 0).is_some()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set(&mut self, fd: u32) {
|
||||
self.bits[(fd as usize) / 64] |= 1 << (fd % 64);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear(&mut self, fd: u32) {
|
||||
self.bits[(fd as usize) / 64] &= !(1 << (fd % 64));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_set(&self, fd: u32) -> bool {
|
||||
self.bits[(fd as usize) / 64] & (1 << (fd % 64)) != 0
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = u32> + '_ {
|
||||
FdSetIter {
|
||||
idx: 0,
|
||||
set: self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for FdSetIter<'_> {
|
||||
type Item = u32;
|
||||
|
||||
fn next(&mut self) -> Option<u32> {
|
||||
while self.idx < 128 {
|
||||
if self.set.is_set(self.idx) {
|
||||
let res = self.idx;
|
||||
self.idx += 1;
|
||||
return Some(res);
|
||||
}
|
||||
self.idx += 1;
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FdSet {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "FdSet {{ ")?;
|
||||
let mut count = 0;
|
||||
for fd in self.iter() {
|
||||
if count != 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{}", fd)?;
|
||||
count += 1;
|
||||
}
|
||||
write!(f, " }}")
|
||||
}
|
||||
}
|
||||
|
||||
impl FileMode {
|
||||
/// Returns default permission set for directories
|
||||
pub const fn default_dir() -> Self {
|
||||
|
||||
Reference in New Issue
Block a user