Consolidate relibc overlay patch chain

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-21 16:15:17 +01:00
parent 19d39068cf
commit ad9254e489
5 changed files with 19 additions and 256 deletions
-115
View File
@@ -1,115 +0,0 @@
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,9 @@
+sys_includes = ["stdint.h"]
+include_guard = "_SYS_EVENTFD_H"
+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,87 @@
+//! `sys/eventfd.h` implementation.
+//!
+//! Non-POSIX, see <https://man7.org/linux/man-pages/man2/eventfd.2.html>.
+
+use core::{mem, slice};
+
+use crate::{
+ c_str::{CStr, CString},
+ 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 path = CString::new(format!(
+ "/scheme/event/eventfd/{}/{}",
+ initval,
+ if flags & EFD_SEMAPHORE == EFD_SEMAPHORE { 1 } else { 0 }
+ ))
+ .map_err(|_| Errno(EINVAL))?;
+
+ Sys::open(CStr::borrow(&path), oflag, 0)
+}
+
+#[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()
+}
@@ -1,25 +1,29 @@
diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs
--- a/src/header/fcntl/mod.rs --- a/src/header/fcntl/mod.rs
+++ b/src/header/fcntl/mod.rs +++ b/src/header/fcntl/mod.rs
@@ -8,7 +8,8 @@ @@ -8,6 +8,7 @@ use crate::{
c_str::CStr, c_str::CStr,
error::ResultExt, error::{Errno, ResultExt},
+ header::unistd::{close, dup}, header::errno::ENAMETOOLONG,
+ header::unistd::close,
platform::{ platform::{
Pal, Sys, Pal, Sys,
types::{c_char, c_int, c_short, c_ulonglong, mode_t, off_t, pid_t}, types::{
}, @@ -78,6 +79,23 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) ->
};
@@ -74,5 +75,17 @@
_ => 0, _ => 0,
}; };
+ if cmd == F_DUPFD_CLOEXEC { + if cmd == F_DUPFD_CLOEXEC {
+ let new_fd = dup(fildes); + let new_fd = Sys::fcntl(fildes, F_DUPFD_CLOEXEC, arg).or_minus_one_errno();
+ if new_fd >= 0 {
+ return new_fd;
+ }
+
+ let new_fd = Sys::fcntl(fildes, F_DUPFD, arg).or_minus_one_errno();
+ if new_fd < 0 { + if new_fd < 0 {
+ return -1; + return -1;
+ } + }
+ if unsafe { fcntl(new_fd, F_SETFD, FD_CLOEXEC as c_ulonglong) } < 0 { + if Sys::fcntl(new_fd, F_SETFD, FD_CLOEXEC as c_ulonglong).or_minus_one_errno() < 0 {
+ let _ = close(new_fd); + let _ = close(new_fd);
+ return -1; + return -1;
+ } + }
@@ -1,114 +1,3 @@
diff --git a/tests/sys_eventfd/eventfd.c b/tests/sys_eventfd/eventfd.c
new file mode 100644
--- /dev/null
+++ b/tests/sys_eventfd/eventfd.c
@@ -0,0 +1,27 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+
+int main(void) {
+ int fd = eventfd(2, 0);
+ assert(fd >= 0);
+ eventfd_t value = 0;
+ assert(eventfd_read(fd, &value) == 0);
+ assert(value == 2);
+ assert(eventfd_write(fd, 5) == 0);
+ assert(eventfd_read(fd, &value) == 0);
+ assert(value == 5);
+ assert(close(fd) == 0);
+
+ int semfd = eventfd(2, EFD_SEMAPHORE);
+ assert(semfd >= 0);
+ assert(eventfd_read(semfd, &value) == 0);
+ assert(value == 1);
+ assert(eventfd_read(semfd, &value) == 0);
+ assert(value == 1);
+ assert(close(semfd) == 0);
+ puts("eventfd ok");
+ return 0;
+}
diff --git a/tests/sys_signalfd/signalfd.c b/tests/sys_signalfd/signalfd.c
new file mode 100644
--- /dev/null
+++ b/tests/sys_signalfd/signalfd.c
@@ -0,0 +1,23 @@
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/signalfd.h>
+#include <unistd.h>
+
+int main(void) {
+ sigset_t mask;
+ assert(sigemptyset(&mask) == 0);
+ assert(sigaddset(&mask, SIGUSR1) == 0);
+ assert(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
+ int fd = signalfd(-1, &mask, sizeof(mask));
+ assert(fd >= 0);
+ assert(kill(getpid(), SIGUSR1) == 0);
+ struct signalfd_siginfo info;
+ assert(read(fd, &info, sizeof(info)) == (ssize_t)sizeof(info));
+ assert(info.ssi_signo == SIGUSR1);
+ assert(info.ssi_pid == (uint32_t)getpid());
+ assert(close(fd) == 0);
+ puts("signalfd ok");
+ return 0;
+}
diff --git a/tests/sys_signalfd/header_only.c b/tests/sys_signalfd/header_only.c
new file mode 100644
--- /dev/null
+++ b/tests/sys_signalfd/header_only.c
@@ -0,0 +1,12 @@
+#include <stdint.h>
+#include <sys/signalfd.h>
+
+int main(void) {
+ struct signalfd_siginfo info = {0};
+ int (*fn1)(int, const sigset_t *, size_t) = signalfd;
+ int (*fn2)(int, const sigset_t *, size_t, int) = signalfd4;
+
+ return (int)sizeof(info)
+ + (fn1 == 0)
+ + (fn2 == 0);
+}
diff --git a/tests/sys_timerfd/timerfd.c b/tests/sys_timerfd/timerfd.c
new file mode 100644
--- /dev/null
+++ b/tests/sys_timerfd/timerfd.c
@@ -0,0 +1,29 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+
+int main(void) {
+ int fd = timerfd_create(CLOCK_REALTIME, 0);
+ assert(fd >= 0);
+ struct itimerspec spec;
+ memset(&spec, 0, sizeof(spec));
+ spec.it_value.tv_nsec = 1000000;
+ assert(timerfd_settime(fd, 0, &spec, NULL) == 0);
+
+ uint64_t expirations = 0;
+ assert(read(fd, &expirations, sizeof(expirations)) == (ssize_t)sizeof(expirations));
+ assert(expirations >= 1);
+
+ struct itimerspec cur;
+ assert(timerfd_gettime(fd, &cur) == 0);
+
+ memset(&spec, 0, sizeof(spec));
+ spec.it_value.tv_sec = 1;
+ assert(timerfd_settime(fd, TFD_TIMER_ABSTIME, &spec, NULL) == 0);
+ assert(close(fd) == 0);
+ puts("timerfd ok");
+ return 0;
+}
diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk
--- a/tests/Makefile.tests.mk --- a/tests/Makefile.tests.mk
+++ b/tests/Makefile.tests.mk +++ b/tests/Makefile.tests.mk
+6 -20
View File
@@ -17,18 +17,18 @@ index 62e98108..a9c72392 100644
return (double)(*val); return (double)(*val);
} }
diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs
index 6a4db2fa..82484375 100644 index ec37906c..95604e06 100644
--- a/src/header/fcntl/mod.rs --- a/src/header/fcntl/mod.rs
+++ b/src/header/fcntl/mod.rs +++ b/src/header/fcntl/mod.rs
@@ -7,6 +7,7 @@ use core::num::NonZeroU64; @@ -8,6 +8,7 @@ use crate::{
use crate::{
c_str::CStr, c_str::CStr,
error::ResultExt, error::{Errno, ResultExt},
header::errno::ENAMETOOLONG,
+ header::unistd::close, + header::unistd::close,
platform::{ platform::{
Pal, Sys, Pal, Sys,
types::{c_char, c_int, c_short, c_ulonglong, mode_t, off_t, pid_t}, types::{
@@ -74,5 +75,22 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) -> @@ -78,6 +79,23 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) ->
_ => 0, _ => 0,
}; };
@@ -51,17 +51,3 @@ index 6a4db2fa..82484375 100644
+ +
Sys::fcntl(fildes, cmd, arg).or_minus_one_errno() Sys::fcntl(fildes, cmd, arg).or_minus_one_errno()
} }
diff --git a/src/header/fcntl/linux.rs b/src/header/fcntl/linux.rs
index 9a3978dc..906ad525 100644
--- a/src/header/fcntl/linux.rs
+++ b/src/header/fcntl/linux.rs
@@ -15,7 +15,7 @@ pub const O_DIRECTORY: c_int = 0x1_0000;
pub const O_NOFOLLOW: c_int = 0x2_0000;
pub const O_CLOEXEC: c_int = 0x8_0000;
pub const O_PATH: c_int = 0x20_0000;
-pub const FD_CLOEXEC: c_int = 0x8_0000;
+pub const FD_CLOEXEC: c_int = 1;
// Defined for compatibility
pub const O_NDELAY: c_int = O_NONBLOCK;
-1
View File
@@ -3,7 +3,6 @@ git = "https://gitlab.redox-os.org/redox-os/relibc.git"
patches = [ patches = [
"../../../local/patches/relibc/redox.patch", "../../../local/patches/relibc/redox.patch",
"../../../local/patches/relibc/P0-strtold-cpp-linkage-and-compat.patch", "../../../local/patches/relibc/P0-strtold-cpp-linkage-and-compat.patch",
"../../../local/patches/relibc/P3-eventfd.patch",
"../../../local/patches/relibc/P3-signalfd.patch", "../../../local/patches/relibc/P3-signalfd.patch",
"../../../local/patches/relibc/P3-signalfd-header.patch", "../../../local/patches/relibc/P3-signalfd-header.patch",
"../../../local/patches/relibc/P3-timerfd.patch", "../../../local/patches/relibc/P3-timerfd.patch",