Files
RedBear-OS/local/patches/relibc/P3-eventfd.patch
T
2026-04-15 12:57:45 +01:00

122 lines
3.6 KiB
Diff

diff -ruN a/src/header/mod.rs b/src/header/mod.rs
--- a/src/header/mod.rs 2026-04-15 09:40:30.417847129 +0100
+++ b/src/header/mod.rs 2026-04-15 09:46:42.009254774 +0100
@@ -89,6 +89,7 @@
// TODO: stropts.h (deprecated)
pub mod sys_auxv;
pub mod sys_epoll;
+pub mod sys_eventfd;
pub mod sys_file;
pub mod sys_ioctl;
// TODO: sys/ipc.h
diff -ruN a/src/header/sys_eventfd/cbindgen.toml b/src/header/sys_eventfd/cbindgen.toml
--- a/src/header/sys_eventfd/cbindgen.toml 1970-01-01 00:00:00.000000000 +0000
+++ b/src/header/sys_eventfd/cbindgen.toml 2026-04-15 09:46:42.009280833 +0100
@@ -0,0 +1,12 @@
+sys_includes = ["stdint.h"]
+include_guard = "_SYS_EVENTFD_H"
+trailer = """
+typedef uint64_t eventfd_t;
+"""
+language = "C"
+style = "Tag"
+no_includes = true
+cpp_compat = true
+
+[enum]
+prefix_with_name = true
diff -ruN a/src/header/sys_eventfd/mod.rs b/src/header/sys_eventfd/mod.rs
--- a/src/header/sys_eventfd/mod.rs 1970-01-01 00:00:00.000000000 +0000
+++ b/src/header/sys_eventfd/mod.rs 2026-04-15 09:46:42.009305629 +0100
@@ -0,0 +1,90 @@
+//! `sys/eventfd.h` implementation.
+//!
+//! Non-POSIX, see <https://man7.org/linux/man-pages/man2/eventfd.2.html>.
+
+use core::{mem, slice};
+
+use crate::{
+ error::{Errno, ResultExt},
+ header::{
+ errno::{EFAULT, EINVAL, EIO},
+ fcntl::{O_CLOEXEC, O_NONBLOCK, O_RDWR},
+ },
+ platform::{
+ ERRNO, Pal, Sys,
+ types::{c_int, c_uint},
+ },
+};
+
+pub const EFD_CLOEXEC: c_int = 0x80000;
+pub const EFD_NONBLOCK: c_int = 0x800;
+pub const EFD_SEMAPHORE: c_int = 0x1;
+pub type eventfd_t = u64;
+
+fn read_exact(fd: c_int, buf: &mut [u8]) -> Result<(), Errno> {
+ match Sys::read(fd, buf)? {
+ n if n == buf.len() => Ok(()),
+ _ => Err(Errno(EIO)),
+ }
+}
+
+fn write_exact(fd: c_int, buf: &[u8]) -> Result<(), Errno> {
+ match Sys::write(fd, buf)? {
+ n if n == buf.len() => Ok(()),
+ _ => Err(Errno(EIO)),
+ }
+}
+
+fn eventfd2_inner(initval: c_uint, flags: c_int) -> Result<c_int, Errno> {
+ let supported = EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE;
+ if flags & !supported != 0 {
+ return Err(Errno(EINVAL));
+ }
+
+ let mut oflag = O_RDWR;
+ if flags & EFD_CLOEXEC == EFD_CLOEXEC {
+ oflag |= O_CLOEXEC;
+ }
+ if flags & EFD_NONBLOCK == EFD_NONBLOCK {
+ oflag |= O_NONBLOCK;
+ }
+
+ let fd = Sys::open(c"/scheme/event".into(), oflag, 0)?;
+ if initval != 0 {
+ let value = u64::from(initval);
+ let buf = unsafe {
+ slice::from_raw_parts((&raw const value).cast::<u8>(), mem::size_of::<u64>())
+ };
+ if let Err(err) = write_exact(fd, buf) {
+ let _ = Sys::close(fd);
+ return Err(err);
+ }
+ }
+ Ok(fd)
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn eventfd2(initval: c_uint, flags: c_int) -> c_int {
+ eventfd2_inner(initval, flags).or_minus_one_errno()
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn eventfd(initval: c_uint, flags: c_int) -> c_int {
+ eventfd2(initval, flags)
+}
+
+#[unsafe(no_mangle)]
+pub unsafe extern "C" fn eventfd_read(fd: c_int, value: *mut eventfd_t) -> c_int {
+ if value.is_null() {
+ ERRNO.set(EFAULT);
+ return -1;
+ }
+ let buf = unsafe { slice::from_raw_parts_mut(value.cast::<u8>(), mem::size_of::<eventfd_t>()) };
+ read_exact(fd, buf).map(|()| 0).or_minus_one_errno()
+}
+
+#[unsafe(no_mangle)]
+pub unsafe extern "C" fn eventfd_write(fd: c_int, value: eventfd_t) -> c_int {
+ let buf = unsafe { slice::from_raw_parts((&raw const value).cast::<u8>(), mem::size_of::<eventfd_t>()) };
+ write_exact(fd, buf).map(|()| 0).or_minus_one_errno()
+}