--- /dev/null 2026-05-03 20:55:05.750445686 +0100 +++ b/src/header/sys_eventfd/mod.rs @@ -0,0 +1,37 @@ +//! `sys/eventfd.h` implementation — eventfd() with EFD_SEMAPHORE/CLOEXEC/NONBLOCK. + +use alloc::format; +use crate::c_str::{CStr, CString}; +use crate::error::{Errno, ResultExt}; +use crate::header::fcntl::{O_CLOEXEC, O_NONBLOCK, O_RDWR}; +use crate::header::errno::EINVAL; +use crate::platform::{Pal, Sys, types::{c_int, c_uint}}; + +pub const EFD_SEMAPHORE: c_int = 1; +pub const EFD_CLOEXEC: c_int = 0x80000; +pub const EFD_NONBLOCK: c_int = 0x800; + +pub type eventfd_t = u64; + +#[unsafe(no_mangle)] +pub extern "C" fn eventfd(initval: c_uint, flags: c_int) -> c_int { + let supported = EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE; + if flags & !supported != 0 { + return Err::(Errno(EINVAL)).or_minus_one_errno(); + } + let sem = if flags & EFD_SEMAPHORE != 0 { 1 } else { 0 }; + let path = format!("/scheme/event/eventfd/{}/{}", initval, sem); + let cpath = match CString::new(path) { + Ok(p) => p, + Err(_) => return Err::(Errno(EINVAL)).or_minus_one_errno(), + }; + + let mut oflag = O_RDWR; + if flags & EFD_CLOEXEC == EFD_CLOEXEC { + oflag |= O_CLOEXEC; + } + if flags & EFD_NONBLOCK == EFD_NONBLOCK { + oflag |= O_NONBLOCK; + } + Sys::open(CStr::borrow(&cpath), oflag, 0).or_minus_one_errno() +}