From 3c88e9178967189aabead31ee4a2d75446cbae17 Mon Sep 17 00:00:00 2001 From: Vasilito Date: Mon, 20 Apr 2026 18:37:35 +0100 Subject: [PATCH] Refine relibc overlay patches and test wiring --- .../P0-strtold-cpp-linkage-and-compat.patch | 28 +- local/patches/relibc/P3-elf64-types.patch | 3 +- local/patches/relibc/P3-fd-event-tests.patch | 56 ++- local/patches/relibc/P3-ifaddrs-net_if.patch | 131 ++++-- local/patches/relibc/P3-open-memstream.patch | 41 ++ local/patches/relibc/P3-semaphore-fixes.patch | 435 ++++++++++++++++++ local/patches/relibc/P3-signalfd-header.patch | 76 +-- local/patches/relibc/P3-socket-cred.patch | 178 +++++++ local/patches/relibc/P3-waitid.patch | 127 ++++- recipes/core/AGENTS.md | 12 +- recipes/core/relibc/recipe.toml | 10 +- recipes/tests/relibc-tests-bins/recipe.toml | 10 + recipes/tests/relibc-tests/recipe.toml | 10 + 13 files changed, 938 insertions(+), 179 deletions(-) create mode 100644 local/patches/relibc/P3-semaphore-fixes.patch create mode 100644 local/patches/relibc/P3-socket-cred.patch diff --git a/local/patches/relibc/P0-strtold-cpp-linkage-and-compat.patch b/local/patches/relibc/P0-strtold-cpp-linkage-and-compat.patch index b02e3971..04e63a82 100644 --- a/local/patches/relibc/P0-strtold-cpp-linkage-and-compat.patch +++ b/local/patches/relibc/P0-strtold-cpp-linkage-and-compat.patch @@ -1,34 +1,15 @@ -diff --git a/src/c/stdlib.c b/src/c/stdlib.c -index 62e98108..a9c72392 100644 ---- a/src/c/stdlib.c -+++ b/src/c/stdlib.c -@@ -4,6 +4,13 @@ long double strtold(const char *nptr, char **endptr) { - return (long double)strtod(nptr, endptr); - } - -+long double relibc_compat_cpp_strtold(const char *nptr, char **endptr) -+ __asm__("_Z7strtoldPKcPPc"); -+ -+long double relibc_compat_cpp_strtold(const char *nptr, char **endptr) { -+ return strtold(nptr, endptr); -+} -+ - double relibc_ldtod(const long double* val) { - return (double)(*val); - } diff --git a/src/header/stdlib/cbindgen.toml b/src/header/stdlib/cbindgen.toml -index 2e02e68a..c2643c49 100644 --- a/src/header/stdlib/cbindgen.toml +++ b/src/header/stdlib/cbindgen.toml -@@ -1,17 +1,4 @@ +@@ -1,21 +1,5 @@ sys_includes = ["stddef.h", "alloca.h", "wchar.h", "features.h"] include_guard = "_RELIBC_STDLIB_H" -trailer = """ --#ifndef _RELIBC_STDLIB_STRTOLD_H --#define _RELIBC_STDLIB_STRTOLD_H +-#ifndef _RELIBC_STDLIB_EXTRA_H +-#define _RELIBC_STDLIB_EXTRA_H - -#ifdef __cplusplus --extern \"C\" { +-extern "C" { -#endif - -long double strtold(const char *nptr, char **endptr); @@ -41,3 +22,4 @@ index 2e02e68a..c2643c49 100644 -""" language = "C" style = "Type" + no_includes = true diff --git a/local/patches/relibc/P3-elf64-types.patch b/local/patches/relibc/P3-elf64-types.patch index 85d6287b..8687ed82 100644 --- a/local/patches/relibc/P3-elf64-types.patch +++ b/local/patches/relibc/P3-elf64-types.patch @@ -1,7 +1,8 @@ -diff -ruN a/src/header/elf/mod.rs b/src/header/elf/mod.rs +diff --git a/src/header/elf/mod.rs b/src/header/elf/mod.rs --- a/src/header/elf/mod.rs +++ b/src/header/elf/mod.rs @@ -9,8 +9,8 @@ + pub type Elf32_Word = uint32_t; pub type Elf32_Sword = int32_t; -pub type Elf64_Word = uint64_t; diff --git a/local/patches/relibc/P3-fd-event-tests.patch b/local/patches/relibc/P3-fd-event-tests.patch index e4e4ad61..993ab7a9 100644 --- a/local/patches/relibc/P3-fd-event-tests.patch +++ b/local/patches/relibc/P3-fd-event-tests.patch @@ -58,6 +58,23 @@ new file mode 100644 + 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 ++#include ++ ++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 @@ -95,36 +112,15 @@ new file mode 100644 diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk --- a/tests/Makefile.tests.mk +++ b/tests/Makefile.tests.mk -@@ -312,6 +312,9 @@ VARIED_NAMES=\ - grp/getgrgid_r \ - grp/getgrnam_r \ - grp/gr_iter \ +@@ -314,8 +314,12 @@ VARIED_NAMES=\ + grp/gr_iter \ + semaphore/named \ + semaphore/unnamed \ + sys_eventfd/eventfd \ ++ sys_signalfd/header_only \ + sys_signalfd/signalfd \ + sys_timerfd/timerfd \ - waitpid \ - waitpid_multiple \ - $(FAILING_TESTS) -diff --git a/tests/Makefile b/tests/Makefile ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -78,14 +78,16 @@ FLAGS=\ - -Wno-deprecated-declarations \ - -pedantic \ - -g \ -- -I . -+ -I . \ -+ $(CPPFLAGS) $(CFLAGS) - - STATIC_FLAGS=\ -- -static -+ -static $(LDFLAGS) - - DYNAMIC_FLAGS=\ - -Wl,--enable-new-dtags \ -- -Wl,-export-dynamic -+ -Wl,-export-dynamic \ -+ $(LDFLAGS) - - SYSROOT?=$(abspath ../sysroot/$(TARGET)/) - SYSROOT_TARGET?=$(SYSROOT) + waitid \ + waitpid \ + waitpid_multiple \ + $(FAILING_TESTS) diff --git a/local/patches/relibc/P3-ifaddrs-net_if.patch b/local/patches/relibc/P3-ifaddrs-net_if.patch index 378412d5..655300d7 100644 --- a/local/patches/relibc/P3-ifaddrs-net_if.patch +++ b/local/patches/relibc/P3-ifaddrs-net_if.patch @@ -17,7 +17,7 @@ index bddb69b8..598beba3 100644 platform::{ self, types::{c_char, c_int, c_uint, c_void}, -@@ -27,6 +33,68 @@ pub struct ifaddrs { +@@ -27,6 +33,83 @@ pub struct ifaddrs { ifa_data: *mut c_void, } @@ -32,11 +32,22 @@ index bddb69b8..598beba3 100644 + } +} + ++fn align_up(offset: usize, align: usize) -> usize { ++ (offset + (align - 1)) & !(align - 1) ++} ++ +unsafe fn make_ifaddrs_node(entry: &crate::header::net_if::InterfaceEntry) -> *mut ifaddrs { + let name_len = entry.name.to_bytes_with_nul().len(); + let addr_size = if entry.addr.is_some() { core::mem::size_of::() } else { 0 }; + let netmask_size = if entry.netmask.is_some() { core::mem::size_of::() } else { 0 }; -+ let total = core::mem::size_of::() + name_len + addr_size + netmask_size; ++ let addr_align = core::mem::align_of::(); ++ let mut total = core::mem::size_of::() + name_len; ++ if addr_size != 0 { ++ total = align_up(total, addr_align) + addr_size; ++ } ++ if netmask_size != 0 { ++ total = align_up(total, addr_align) + netmask_size; ++ } + let raw = unsafe { stdlib::malloc(total) } as *mut u8; + if raw.is_null() { + return core::ptr::null_mut(); @@ -52,6 +63,8 @@ index bddb69b8..598beba3 100644 + cursor = unsafe { cursor.add(name_len) }; + + let addr_ptr = if let Some(addr) = entry.addr { ++ let aligned = align_up(cursor as usize, addr_align); ++ cursor = aligned as *mut u8; + let ptr = cursor.cast::(); + unsafe { ptr.write(ipv4_addr(addr)) }; + cursor = unsafe { cursor.add(core::mem::size_of::()) }; @@ -61,6 +74,8 @@ index bddb69b8..598beba3 100644 + }; + + let netmask_ptr = if let Some(netmask) = entry.netmask { ++ let aligned = align_up(cursor as usize, addr_align); ++ cursor = aligned as *mut u8; + let ptr = cursor.cast::(); + unsafe { ptr.write(ipv4_addr(netmask)) }; + ptr.cast::() @@ -125,7 +140,7 @@ diff --git a/src/header/net_if/mod.rs b/src/header/net_if/mod.rs index edbfedec..bd07e2c9 100644 --- a/src/header/net_if/mod.rs +++ b/src/header/net_if/mod.rs -@@ -21,21 +21,54 @@ pub struct if_nameindex { +@@ -21,21 +21,51 @@ pub struct if_nameindex { if_name: *const c_char, } @@ -171,23 +186,20 @@ index edbfedec..bd07e2c9 100644 - if_name: null::(), - }, -]; -+fn interface_nameindex_table() -> [if_nameindex; 3] { -+ let entries = interface_entries(); -+ [ -+ if_nameindex { -+ if_index: entries[0].index, -+ if_name: entries[0].name.as_ptr(), -+ }, -+ if_nameindex { -+ if_index: entries[1].index, -+ if_name: entries[1].name.as_ptr(), -+ }, -+ if_nameindex { -+ if_index: 0, -+ if_name: null::(), -+ }, -+ ] -+} ++const INTERFACES: [if_nameindex; 3] = [ ++ if_nameindex { ++ if_index: 1, ++ if_name: (c"loopback").as_ptr(), ++ }, ++ if_nameindex { ++ if_index: 2, ++ if_name: (c"eth0").as_ptr(), ++ }, ++ if_nameindex { ++ if_index: 0, ++ if_name: null::(), ++ }, ++]; /// See . /// @@ -215,26 +227,8 @@ index edbfedec..bd07e2c9 100644 } ERRNO.set(ENXIO); null::() -@@ -66,7 +112,17 @@ pub unsafe extern "C" fn if_indextoname(idx: c_uint, buf: *mut c_char) -> *const - /// The end of the list is determined by an if_nameindex struct having if_index 0 and if_name NULL - #[unsafe(no_mangle)] - pub unsafe extern "C" fn if_nameindex() -> *const if_nameindex { -- core::ptr::from_ref::(&INTERFACES[0]) -+ static mut TABLE: [if_nameindex; 3] = [ -+ if_nameindex { if_index: 0, if_name: core::ptr::null() }, -+ if_nameindex { if_index: 0, if_name: core::ptr::null() }, -+ if_nameindex { if_index: 0, if_name: core::ptr::null() }, -+ ]; -+ -+ let computed = interface_nameindex_table(); -+ unsafe { -+ TABLE = computed; -+ core::ptr::from_ref::(&TABLE[0]) -+ } - } - - /// See . -@@ -80,8 +136,11 @@ pub unsafe extern "C" fn if_nametoindex(name: *const c_char) -> c_uint { +@@ -78,9 +136,12 @@ pub unsafe extern "C" fn if_nametoindex(name: *const c_char) -> c_uint { + if name.is_null() { return 0; } let name = unsafe { CStr::from_ptr(name).to_str().unwrap_or("") }; @@ -248,3 +242,60 @@ index edbfedec..bd07e2c9 100644 } 0 } +diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk +--- a/tests/Makefile.tests.mk ++++ b/tests/Makefile.tests.mk +@@ -63,6 +63,7 @@ VARIED_NAMES=\ + features \ + fnmatch \ + glob \ ++ ifaddrs/getifaddrs \ + iso646 \ + libgen \ + locale/duplocale \ +diff --git a/tests/ifaddrs/getifaddrs.c b/tests/ifaddrs/getifaddrs.c +new file mode 100644 +--- /dev/null ++++ b/tests/ifaddrs/getifaddrs.c +@@ -0,0 +1,41 @@ ++#include ++#include ++#include ++#include ++#include ++ ++int main(void) { ++ struct ifaddrs *list = NULL; ++ struct ifaddrs *it; ++ const struct if_nameindex *names; ++ char name[IF_NAMESIZE] = {0}; ++ int saw_loopback = 0; ++ int saw_eth0 = 0; ++ ++ assert(getifaddrs(&list) == 0); ++ for (it = list; it != NULL; it = it->ifa_next) { ++ assert(it->ifa_name != NULL); ++ if (strcmp(it->ifa_name, "loopback") == 0) { ++ saw_loopback = 1; ++ assert((it->ifa_flags & IFF_LOOPBACK) != 0); ++ } else if (strcmp(it->ifa_name, "eth0") == 0) { ++ saw_eth0 = 1; ++ assert(if_nametoindex("eth0") == 2); ++ assert(if_indextoname(2, name) == name); ++ assert(strcmp(name, "eth0") == 0); ++ } ++ } ++ ++ names = if_nameindex(); ++ assert(names != NULL); ++ assert(names[0].if_index == 1 && strcmp(names[0].if_name, "loopback") == 0); ++ assert(names[1].if_index == 2 && strcmp(names[1].if_name, "eth0") == 0); ++ assert(names[2].if_index == 0 && names[2].if_name == NULL); ++ ++ assert(saw_loopback != 0); ++ assert(saw_eth0 != 0); ++ if_freenameindex((struct if_nameindex *)names); ++ freeifaddrs(list); ++ puts("getifaddrs ok"); ++ return 0; ++} diff --git a/local/patches/relibc/P3-open-memstream.patch b/local/patches/relibc/P3-open-memstream.patch index b5e251a0..13521090 100644 --- a/local/patches/relibc/P3-open-memstream.patch +++ b/local/patches/relibc/P3-open-memstream.patch @@ -138,3 +138,44 @@ new file mode 100644 +pub unsafe extern "C" fn open_memstream(bufp: *mut *mut c_char, sizep: *mut size_t) -> *mut FILE { + create_memstream(bufp, sizep).or_errno_null_mut() +} +diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk +--- a/tests/Makefile.tests.mk ++++ b/tests/Makefile.tests.mk +@@ -85,6 +85,7 @@ VARIED_NAMES=\ + stdio/fseek \ + stdio/fwrite \ + stdio/getc_unget \ +- stdio/getline \ ++ stdio/getline \ ++ stdio/open_memstream \ + stdio/mutex \ + stdio/popen \ +diff --git a/tests/stdio/open_memstream.c b/tests/stdio/open_memstream.c +new file mode 100644 +--- /dev/null ++++ b/tests/stdio/open_memstream.c +@@ -0,0 +1,24 @@ ++#include ++#include ++#include ++#include ++ ++int main(void) { ++ char *buf = NULL; ++ size_t size = 0; ++ ++ FILE *stream = open_memstream(&buf, &size); ++ assert(stream != NULL); ++ assert(fputs("hello", stream) >= 0); ++ assert(fflush(stream) == 0); ++ assert(size == 5); ++ assert(strcmp(buf, "hello") == 0); ++ assert(fputc('!', stream) != EOF); ++ assert(fclose(stream) == 0); ++ assert(size == 6); ++ assert(strcmp(buf, "hello!") == 0); ++ ++ free(buf); ++ puts("open_memstream ok"); ++ return 0; ++} diff --git a/local/patches/relibc/P3-semaphore-fixes.patch b/local/patches/relibc/P3-semaphore-fixes.patch new file mode 100644 index 00000000..57271562 --- /dev/null +++ b/local/patches/relibc/P3-semaphore-fixes.patch @@ -0,0 +1,435 @@ +diff --git a/src/sync/semaphore.rs b/src/sync/semaphore.rs +--- a/src/sync/semaphore.rs ++++ b/src/sync/semaphore.rs +@@ -2,8 +2,10 @@ + //TODO: improve implementation + + use crate::{ ++ error::{Errno, Result}, + header::{ + bits_timespec::timespec, ++ errno::{EINVAL, ETIMEDOUT}, + time::{CLOCK_MONOTONIC, CLOCK_REALTIME, timespec_realtime_to_monotonic}, + }, + platform::types::{c_uint, clockid_t}, +@@ -30,12 +32,12 @@ + crate::sync::futex_wake(&self.count, i32::MAX); + } + +- pub fn try_wait(&self) -> u32 { ++ pub fn try_wait(&self) -> bool { + loop { + let value = self.count.load(Ordering::SeqCst); + + if value == 0 { +- return 0; ++ return false; + } + + match self.count.compare_exchange_weak( +@@ -45,20 +47,16 @@ + Ordering::SeqCst, + ) { + Ok(_) => { +- // Acquired +- return value; ++ return true; + } + Err(_) => (), + } +- // Try again (as long as value > 0) + } + } + +- pub fn wait(&self, timeout_opt: Option<×pec>, clock_id: clockid_t) -> Result<(), ()> { ++ pub fn wait(&self, timeout_opt: Option<×pec>, clock_id: clockid_t) -> Result<()> { + loop { +- let value = self.try_wait(); +- +- if value == 0 { ++ if self.try_wait() { + return Ok(()); + } + +@@ -68,17 +66,20 @@ + CLOCK_MONOTONIC => timeout.clone(), + CLOCK_REALTIME => match timespec_realtime_to_monotonic(timeout.clone()) { + Ok(relative) => relative, +- Err(_) => return Err(()), ++ Err(_) => return Err(Errno(EINVAL)), + }, +- _ => return Err(()), ++ _ => return Err(Errno(EINVAL)), + }; +- crate::sync::futex_wait(&self.count, value, Some(&relative)); ++ match crate::sync::futex_wait(&self.count, 0, Some(&relative)) { ++ crate::sync::FutexWaitResult::TimedOut => return Err(Errno(ETIMEDOUT)), ++ crate::sync::FutexWaitResult::Waited | crate::sync::FutexWaitResult::Stale => {} ++ } + } else { +- // Use futex to wait for the next change, without a timeout +- crate::sync::futex_wait(&self.count, value, None); ++ crate::sync::futex_wait(&self.count, 0, None); + } + } + } ++ + pub fn value(&self) -> c_uint { + self.count.load(Ordering::SeqCst) + } +diff --git a/src/header/semaphore/mod.rs b/src/header/semaphore/mod.rs +--- a/src/header/semaphore/mod.rs ++++ b/src/header/semaphore/mod.rs +@@ -3,12 +3,20 @@ + //! See . + + use crate::{ ++ error::{Errno, ResultExt}, + header::{ + bits_timespec::timespec, ++ errno::{EAGAIN, EINVAL}, ++ fcntl::{O_CREAT, O_EXCL, O_RDWR}, ++ sys_mman::{MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE, mmap, munmap, shm_open, shm_unlink}, ++ sys_stat::stat, + time::{CLOCK_MONOTONIC, CLOCK_REALTIME}, ++ unistd::close, + }, +- platform::types::{c_char, c_int, c_long, c_uint, clockid_t}, ++ out::Out, ++ platform::{ERRNO, Pal, Sys, types::{c_char, c_int, c_long, c_uint, clockid_t, mode_t, c_void}}, + }; ++use core::{mem, ptr}; + + /// See . + // TODO: Statically verify size and align +@@ -20,10 +28,90 @@ + } + pub type RlctSempahore = crate::sync::Semaphore; + ++#[repr(C)] ++struct NamedSemaphore { ++ sem: RlctSempahore, ++} ++ ++const SEM_FAILED_PTR: *mut sem_t = usize::MAX as *mut sem_t; ++ ++unsafe fn map_named_semaphore( ++ name: *const c_char, ++ oflag: c_int, ++ mode: mode_t, ++ value: c_uint, ++) -> Result<*mut sem_t, Errno> { ++ if name.is_null() { ++ return Err(Errno(EINVAL)); ++ } ++ ++ let mut shm_flags = O_RDWR; ++ if oflag & O_CREAT == O_CREAT { ++ shm_flags |= O_CREAT; ++ } ++ if oflag & O_EXCL == O_EXCL { ++ shm_flags |= O_EXCL; ++ } ++ ++ let fd = unsafe { shm_open(name, shm_flags, mode) }; ++ if fd < 0 { ++ return Err(Errno(ERRNO.get())); ++ } ++ ++ let mut st = stat::default(); ++ if let Err(err) = Sys::fstat(fd, Out::from_mut(&mut st)) { ++ let _ = close(fd); ++ return Err(err); ++ } ++ ++ let size = mem::size_of::() as i64; ++ let created = st.st_size == 0; ++ if created { ++ if let Err(err) = Sys::ftruncate(fd, size) { ++ let _ = close(fd); ++ return Err(err); ++ } ++ } else if st.st_size < size { ++ let _ = close(fd); ++ return Err(Errno(EINVAL)); ++ } ++ ++ let mapped = unsafe { ++ mmap( ++ ptr::null_mut(), ++ size as usize, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, ++ fd, ++ 0, ++ ) ++ }; ++ let _ = close(fd); ++ if mapped == MAP_FAILED { ++ return Err(Errno(ERRNO.get())); ++ } ++ ++ let named = mapped.cast::(); ++ if created { ++ unsafe { ++ named.write(NamedSemaphore { ++ sem: RlctSempahore::new(value), ++ }); ++ } ++ } ++ ++ Ok(named.cast()) ++} ++ + /// See . +-// #[unsafe(no_mangle)] ++#[unsafe(no_mangle)] + pub unsafe extern "C" fn sem_close(sem: *mut sem_t) -> c_int { +- todo!("named semaphores") ++ if sem.is_null() || sem == SEM_FAILED_PTR { ++ ERRNO.set(EINVAL); ++ return -1; ++ } ++ ++ unsafe { munmap(sem.cast::(), mem::size_of::()) } + } + + /// See . +@@ -51,12 +139,25 @@ + + /// See . + // TODO: va_list +-// #[unsafe(no_mangle)] ++#[unsafe(no_mangle)] + pub unsafe extern "C" fn sem_open( + name: *const c_char, +- oflag: c_int, /* (va_list) value: c_uint */ ++ oflag: c_int, ++ mut args: ..., + ) -> *mut sem_t { +- todo!("named semaphores") ++ let (mode, value) = if oflag & O_CREAT == O_CREAT { ++ (unsafe { args.arg::() }, unsafe { args.arg::() }) ++ } else { ++ (0o600 as mode_t, 0) ++ }; ++ ++ match unsafe { map_named_semaphore(name, oflag, mode, value) } { ++ Ok(sem) => sem, ++ Err(Errno(errno)) => { ++ ERRNO.set(errno); ++ SEM_FAILED_PTR ++ } ++ } + } + + /// See . +@@ -70,23 +171,27 @@ + /// See . + #[unsafe(no_mangle)] + pub unsafe extern "C" fn sem_trywait(sem: *mut sem_t) -> c_int { +- unsafe { get(sem) }.try_wait(); +- +- 0 ++ if unsafe { get(sem) }.try_wait() { ++ 0 ++ } else { ++ crate::platform::ERRNO.set(EAGAIN); ++ -1 ++ } + } + + /// See . +-// #[unsafe(no_mangle)] ++#[unsafe(no_mangle)] + pub unsafe extern "C" fn sem_unlink(name: *const c_char) -> c_int { +- todo!("named semaphores") ++ unsafe { shm_unlink(name) } + } + + /// See . + #[unsafe(no_mangle)] + pub unsafe extern "C" fn sem_wait(sem: *mut sem_t) -> c_int { +- if let Ok(()) = unsafe { get(sem) }.wait(None, CLOCK_MONOTONIC) {}; // TODO handle error +- +- 0 ++ unsafe { get(sem) } ++ .wait(None, CLOCK_MONOTONIC) ++ .map(|()| 0) ++ .or_minus_one_errno() + } + + /// See . +@@ -96,18 +201,19 @@ + clock_id: clockid_t, + abstime: *const timespec, + ) -> c_int { +- if let Ok(()) = unsafe { get(sem) }.wait(Some(&unsafe { (*abstime).clone() }), clock_id) {}; // TODO handle error +- +- 0 ++ unsafe { get(sem) } ++ .wait(Some(&unsafe { (*abstime).clone() }), clock_id) ++ .map(|()| 0) ++ .or_minus_one_errno() + } + + /// See . + #[unsafe(no_mangle)] + pub unsafe extern "C" fn sem_timedwait(sem: *mut sem_t, abstime: *const timespec) -> c_int { +- if let Ok(()) = unsafe { get(sem) }.wait(Some(&unsafe { (*abstime).clone() }), CLOCK_REALTIME) { +- }; // TODO handle error +- +- 0 ++ unsafe { get(sem) } ++ .wait(Some(&unsafe { (*abstime).clone() }), CLOCK_REALTIME) ++ .map(|()| 0) ++ .or_minus_one_errno() + } + + unsafe fn get<'any>(sem: *mut sem_t) -> &'any RlctSempahore { +diff --git a/src/header/semaphore/cbindgen.toml b/src/header/semaphore/cbindgen.toml +--- a/src/header/semaphore/cbindgen.toml ++++ b/src/header/semaphore/cbindgen.toml +@@ -2,6 +2,9 @@ + include_guard = "_RELIBC_SEMAPHORE_H" + after_includes = """ + #include // for timespec ++""" ++trailer = """ ++#define SEM_FAILED ((sem_t *) -1) + """ + language = "C" + style = "Type" +diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk +--- a/tests/Makefile.tests.mk ++++ b/tests/Makefile.tests.mk +@@ -312,6 +312,8 @@ + grp/getgrgid_r \ + grp/getgrnam_r \ + grp/gr_iter \ ++ semaphore/named \ ++ semaphore/unnamed \ + waitid \ + waitpid \ + waitpid_multiple \ +diff --git a/tests/semaphore/unnamed.c b/tests/semaphore/unnamed.c +new file mode 100644 +--- /dev/null ++++ b/tests/semaphore/unnamed.c +@@ -0,0 +1,57 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static sem_t sem; ++ ++static void *post_after_delay(void *arg) ++{ ++ (void)arg; ++ usleep(50000); ++ assert(sem_post(&sem) == 0); ++ return NULL; ++} ++ ++static long elapsed_ns(const struct timespec *start, const struct timespec *end) ++{ ++ return (end->tv_sec - start->tv_sec) * 1000000000L + (end->tv_nsec - start->tv_nsec); ++} ++ ++int main(void) ++{ ++ assert(sem_init(&sem, 0, 0) == 0); ++ ++ errno = 0; ++ assert(sem_trywait(&sem) == -1); ++ assert(errno == EAGAIN); ++ ++ struct timespec deadline; ++ assert(clock_gettime(CLOCK_REALTIME, &deadline) == 0); ++ deadline.tv_nsec += 20000000L; ++ if (deadline.tv_nsec >= 1000000000L) { ++ deadline.tv_sec += 1; ++ deadline.tv_nsec -= 1000000000L; ++ } ++ ++ errno = 0; ++ assert(sem_timedwait(&sem, &deadline) == -1); ++ assert(errno == ETIMEDOUT); ++ ++ pthread_t thread; ++ assert(pthread_create(&thread, NULL, post_after_delay, NULL) == 0); ++ ++ struct timespec start; ++ struct timespec end; ++ assert(clock_gettime(CLOCK_MONOTONIC, &start) == 0); ++ assert(sem_wait(&sem) == 0); ++ assert(clock_gettime(CLOCK_MONOTONIC, &end) == 0); ++ assert(elapsed_ns(&start, &end) >= 20000000L); ++ ++ assert(pthread_join(thread, NULL) == 0); ++ assert(sem_destroy(&sem) == 0); ++ ++ return 0; ++} +diff --git a/tests/semaphore/named.c b/tests/semaphore/named.c +new file mode 100644 +--- /dev/null ++++ b/tests/semaphore/named.c +@@ -0,0 +1,54 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static sem_t *first; ++static sem_t *second; ++ ++static void *post_after_delay(void *arg) ++{ ++ (void)arg; ++ usleep(50000); ++ assert(sem_post(second) == 0); ++ return NULL; ++} ++ ++static long elapsed_ns(const struct timespec *start, const struct timespec *end) ++{ ++ return (end->tv_sec - start->tv_sec) * 1000000000L + (end->tv_nsec - start->tv_nsec); ++} ++ ++int main(void) ++{ ++ char name[64]; ++ snprintf(name, sizeof(name), "/relibc_named_sem_%ld", (long)getpid()); ++ ++ sem_unlink(name); ++ ++ first = sem_open(name, O_CREAT | O_EXCL, 0600, 0); ++ assert(first != SEM_FAILED); ++ second = sem_open(name, 0); ++ assert(second != SEM_FAILED); ++ ++ pthread_t thread; ++ assert(pthread_create(&thread, NULL, post_after_delay, NULL) == 0); ++ ++ struct timespec start; ++ struct timespec end; ++ assert(clock_gettime(CLOCK_MONOTONIC, &start) == 0); ++ assert(sem_wait(first) == 0); ++ assert(clock_gettime(CLOCK_MONOTONIC, &end) == 0); ++ assert(elapsed_ns(&start, &end) >= 20000000L); ++ ++ assert(pthread_join(thread, NULL) == 0); ++ assert(sem_close(second) == 0); ++ assert(sem_close(first) == 0); ++ assert(sem_unlink(name) == 0); ++ ++ return 0; ++} diff --git a/local/patches/relibc/P3-signalfd-header.patch b/local/patches/relibc/P3-signalfd-header.patch index 77a79bb7..625a7fa1 100644 --- a/local/patches/relibc/P3-signalfd-header.patch +++ b/local/patches/relibc/P3-signalfd-header.patch @@ -1,18 +1,10 @@ -diff -ruN a/src/header/mod.rs b/src/header/mod.rs ---- a/src/header/mod.rs 2026-04-15 09:48:02.257700000 +0100 -+++ b/src/header/mod.rs 2026-04-19 13:30:00.000000000 +0100 -@@ -98,6 +98,7 @@ - pub mod sys_resource; - pub mod sys_select; -+pub mod sys_signalfd; - // TODO: sys/sem.h - // TODO: sys/shm.h - pub mod sys_socket; -diff -ruN a/src/header/sys_signalfd/cbindgen.toml b/src/header/sys_signalfd/cbindgen.toml ---- a/src/header/sys_signalfd/cbindgen.toml 1970-01-01 00:00:00.000000000 +0000 -+++ b/src/header/sys_signalfd/cbindgen.toml 2026-04-15 09:48:02.257754724 +0100 -@@ -0,0 +1,41 @@ -+sys_includes = ["signal.h", "stdint.h"] +diff --git a/src/header/mod.rs b/src/header/mod.rs +diff --git a/src/header/sys_signalfd/cbindgen.toml b/src/header/sys_signalfd/cbindgen.toml +new file mode 100644 +--- /dev/null ++++ b/src/header/sys_signalfd/cbindgen.toml +@@ -0,0 +1,24 @@ ++sys_includes = ["signal.h", "stdint.h", "stddef.h"] +include_guard = "_SYS_SIGNALFD_H" +trailer = """ +#ifndef SFD_CLOEXEC @@ -23,45 +15,24 @@ diff -ruN a/src/header/sys_signalfd/cbindgen.toml b/src/header/sys_signalfd/cbin +#define SFD_NONBLOCK 0x800 +#endif + -+struct signalfd_siginfo { -+ uint32_t ssi_signo; -+ int32_t ssi_errno; -+ int32_t ssi_code; -+ uint32_t ssi_pid; -+ uint32_t ssi_uid; -+ int32_t ssi_fd; -+ uint32_t ssi_tid; -+ uint32_t ssi_band; -+ uint32_t ssi_overrun; -+ uint32_t ssi_trapno; -+ int32_t ssi_status; -+ int32_t ssi_int; -+ uint64_t ssi_ptr; -+ uint64_t ssi_utime; -+ uint64_t ssi_stime; -+ uint64_t ssi_addr; -+ uint16_t ssi_addr_lsb; -+ uint16_t __pad2; -+ int32_t ssi_syscall; -+ uint64_t ssi_call_addr; -+ uint32_t ssi_arch; -+ uint8_t __pad[28]; -+}; ++int signalfd(int fd, const sigset_t *mask, size_t masksize); ++int signalfd4(int fd, const sigset_t *mask, size_t masksize, int flags); +""" +language = "C" +style = "Tag" +no_includes = true +cpp_compat = true - ++ +[enum] +prefix_with_name = true - ++ +[export.rename] +"signalfd_siginfo" = "struct signalfd_siginfo" -diff -ruN a/src/header/sys_signalfd/mod.rs b/src/header/sys_signalfd/mod.rs ---- a/src/header/sys_signalfd/mod.rs 1970-01-01 00:00:00.000000000 +0000 -+++ b/src/header/sys_signalfd/mod.rs 2026-04-15 09:48:02.257778048 +0100 -@@ -0,0 +1,29 @@ +diff --git a/src/header/sys_signalfd/mod.rs b/src/header/sys_signalfd/mod.rs +new file mode 100644 +--- /dev/null ++++ b/src/header/sys_signalfd/mod.rs +@@ -0,0 +1,14 @@ +//! `sys/signalfd.h` implementation. + +use crate::{ @@ -73,21 +44,6 @@ diff -ruN a/src/header/sys_signalfd/mod.rs b/src/header/sys_signalfd/mod.rs +pub const SFD_NONBLOCK: c_int = signal::SFD_NONBLOCK; + +#[unsafe(no_mangle)] -+pub unsafe extern "C" fn signalfd(fd: c_int, mask: *const sigset_t, masksize: usize) -> c_int { -+ unsafe { signal::signalfd(fd, mask, masksize) } -+} -+ -+#[unsafe(no_mangle)] -+pub unsafe extern "C" fn signalfd4( -+ fd: c_int, -+ mask: *const sigset_t, -+ masksize: usize, -+ flags: c_int, -+) -> c_int { -+ unsafe { signal::signalfd4(fd, mask, masksize, flags) } -+} -+ -+#[unsafe(no_mangle)] +pub extern "C" fn _cbindgen_export_sys_signalfd_siginfo(siginfo: signalfd_siginfo) { + let _ = siginfo; +} diff --git a/local/patches/relibc/P3-socket-cred.patch b/local/patches/relibc/P3-socket-cred.patch new file mode 100644 index 00000000..bfda9911 --- /dev/null +++ b/local/patches/relibc/P3-socket-cred.patch @@ -0,0 +1,178 @@ +diff --git a/src/header/sys_socket/mod.rs b/src/header/sys_socket/mod.rs +--- a/src/header/sys_socket/mod.rs ++++ b/src/header/sys_socket/mod.rs +@@ -5,7 +5,7 @@ + use core::{mem, ptr}; + + use crate::{ +- error::ResultExt, ++ error::{Errno, ResultExt}, + header::{bits_iovec::iovec, bits_safamily_t::sa_family_t, bits_socklen_t::socklen_t}, + platform::{ + PalSocket, Sys, +@@ -236,6 +236,48 @@ + socket, + address, + address_len ++ ) ++} ++ ++#[unsafe(no_mangle)] ++pub unsafe extern "C" fn getpeereid(socket: c_int, euid: *mut uid_t, egid: *mut gid_t) -> c_int { ++ trace_expr!( ++ (|| { ++ if euid.is_null() || egid.is_null() { ++ return Err(Errno(crate::header::errno::EFAULT)); ++ } ++ ++ let mut cred = ucred { ++ pid: 0, ++ uid: 0, ++ gid: 0, ++ }; ++ let mut len = mem::size_of::() as socklen_t; ++ unsafe { ++ Sys::getsockopt( ++ socket, ++ constants::SOL_SOCKET, ++ constants::SO_PEERCRED, ++ &mut cred as *mut ucred as *mut c_void, ++ &mut len, ++ )?; ++ } ++ ++ if (len as usize) < mem::size_of::() { ++ return Err(Errno(crate::header::errno::EINVAL)); ++ } ++ ++ unsafe { ++ *euid = cred.uid; ++ *egid = cred.gid; ++ } ++ Ok(0) ++ })() ++ .or_minus_one_errno(), ++ "getpeereid({}, {:p}, {:p})", ++ socket, ++ euid, ++ egid + ) + } + +diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk +--- a/tests/Makefile.tests.mk ++++ b/tests/Makefile.tests.mk +@@ -137,6 +137,8 @@ + string/stpcpy \ + string/stpncpy \ + strings \ ++ sys_socket/passcred \ ++ sys_socket/peercred \ + sys_socket/recv \ + sys_socket/recvfrom \ + sys_socket/unixrecv \ +diff --git a/tests/sys_socket/peercred.c b/tests/sys_socket/peercred.c +new file mode 100644 +--- /dev/null ++++ b/tests/sys_socket/peercred.c +@@ -0,0 +1,33 @@ ++#include ++#include ++#include ++#include ++ ++#include "test_helpers.h" ++ ++int main(void) ++{ ++ int sv[2]; ++ int status = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); ++ ERROR_IF(socketpair, status, == -1); ++ ++ struct ucred cred; ++ socklen_t len = sizeof(cred); ++ status = getsockopt(sv[0], SOL_SOCKET, SO_PEERCRED, &cred, &len); ++ ERROR_IF(getsockopt, status, == -1); ++ assert(len == sizeof(cred)); ++ assert(cred.uid == getuid()); ++ assert(cred.gid == getgid()); ++ assert(cred.pid > 0); ++ ++ uid_t euid; ++ gid_t egid; ++ status = getpeereid(sv[0], &euid, &egid); ++ ERROR_IF(getpeereid, status, == -1); ++ assert(euid == getuid()); ++ assert(egid == getgid()); ++ ++ close(sv[0]); ++ close(sv[1]); ++ return 0; ++} +diff --git a/tests/sys_socket/passcred.c b/tests/sys_socket/passcred.c +new file mode 100644 +--- /dev/null ++++ b/tests/sys_socket/passcred.c +@@ -0,0 +1,62 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include "test_helpers.h" ++ ++int main(void) ++{ ++ int sv[2]; ++ int status = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); ++ ERROR_IF(socketpair, status, == -1); ++ ++ int one = 1; ++ status = setsockopt(sv[1], SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); ++ ERROR_IF(setsockopt, status, == -1); ++ ++ const char payload[] = "x"; ++ ssize_t sent = send(sv[0], payload, sizeof(payload), 0); ++ ERROR_IF(send, sent, == -1); ++ assert(sent == (ssize_t)sizeof(payload)); ++ ++ char byte = '\0'; ++ struct iovec iov = { ++ .iov_base = &byte, ++ .iov_len = sizeof(byte), ++ }; ++ union { ++ char buf[CMSG_SPACE(sizeof(struct ucred))]; ++ struct cmsghdr align; ++ } control; ++ memset(&control, 0, sizeof(control)); ++ ++ struct msghdr msg = { ++ .msg_name = NULL, ++ .msg_namelen = 0, ++ .msg_iov = &iov, ++ .msg_iovlen = 1, ++ .msg_control = control.buf, ++ .msg_controllen = sizeof(control.buf), ++ .msg_flags = 0, ++ }; ++ ++ ssize_t recvd = recvmsg(sv[1], &msg, 0); ++ ERROR_IF(recvmsg, recvd, == -1); ++ assert(recvd == (ssize_t)sizeof(payload)); ++ assert(byte == 'x'); ++ ++ struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); ++ assert(cmsg != NULL); ++ assert(cmsg->cmsg_level == SOL_SOCKET); ++ assert(cmsg->cmsg_type == SCM_CREDENTIALS); ++ struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg); ++ assert(cred->uid == getuid()); ++ assert(cred->gid == getgid()); ++ assert(cred->pid > 0); ++ ++ close(sv[0]); ++ close(sv[1]); ++ return 0; ++} diff --git a/local/patches/relibc/P3-waitid.patch b/local/patches/relibc/P3-waitid.patch index 4675a81e..d8bd2574 100644 --- a/local/patches/relibc/P3-waitid.patch +++ b/local/patches/relibc/P3-waitid.patch @@ -1,8 +1,7 @@ diff --git a/src/header/sys_wait/mod.rs b/src/header/sys_wait/mod.rs -index 11f4bf2c..23e1a356 100644 --- a/src/header/sys_wait/mod.rs +++ b/src/header/sys_wait/mod.rs -@@ -4,13 +4,17 @@ +@@ -4,12 +4,16 @@ use crate::{ error::ResultExt, @@ -15,14 +14,13 @@ index 11f4bf2c..23e1a356 100644 + types::{c_int, c_uint, pid_t}, }, }; - ++ +pub type idtype_t = c_int; +pub type id_t = c_uint; -+ + pub const WNOHANG: c_int = 1; pub const WUNTRACED: c_int = 2; - -@@ -24,25 +28,112 @@ pub const __WALL: c_int = 0x4000_0000; +@@ -24,25 +28,143 @@ #[allow(overflowing_literals)] pub const __WCLONE: c_int = 0x8000_0000; @@ -37,13 +35,33 @@ index 11f4bf2c..23e1a356 100644 +pub const CLD_STOPPED: c_int = 5; +pub const CLD_CONTINUED: c_int = 6; + -+fn wexitstatus(status: c_int) -> c_int { (status >> 8) & 0xff } -+fn wtermsig(status: c_int) -> c_int { status & 0x7f } -+fn wstopsig(status: c_int) -> c_int { wexitstatus(status) } -+fn wcoredump(status: c_int) -> bool { (status & 0x80) != 0 } -+fn wifexited(status: c_int) -> bool { (status & 0x7f) == 0 } -+fn wifstopped(status: c_int) -> bool { (status & 0xff) == 0x7f } -+fn wifcontinued(status: c_int) -> bool { status == 0xffff } ++fn wexitstatus(status: c_int) -> c_int { ++ (status >> 8) & 0xff ++} ++ ++fn wtermsig(status: c_int) -> c_int { ++ status & 0x7f ++} ++ ++fn wstopsig(status: c_int) -> c_int { ++ wexitstatus(status) ++} ++ ++fn wcoredump(status: c_int) -> bool { ++ (status & 0x80) != 0 ++} ++ ++fn wifexited(status: c_int) -> bool { ++ (status & 0x7f) == 0 ++} ++ ++fn wifstopped(status: c_int) -> bool { ++ (status & 0xff) == 0x7f ++} ++ ++fn wifcontinued(status: c_int) -> bool { ++ status == 0xffff ++} + /// See . #[unsafe(no_mangle)] @@ -89,6 +107,10 @@ index 11f4bf2c..23e1a356 100644 + if options & WCONTINUED != 0 { + waitpid_options |= WCONTINUED; + } ++ if options & WNOWAIT != 0 { ++ waitpid_options |= WNOWAIT; ++ } ++ + Some(waitpid_options) +} + @@ -114,12 +136,15 @@ index 11f4bf2c..23e1a356 100644 + }; + + let mut status = 0; -+ let pid = Sys::waitpid(pid_target, Some(Out::from_mut(&mut status)), waitpid_options).or_minus_one_errno(); ++ let pid = Sys::waitpid(pid_target, Some(Out::from_mut(&mut status)), waitpid_options) ++ .or_minus_one_errno(); + if pid < 0 { + return -1; + } + -+ unsafe { *infop = core::mem::zeroed() }; ++ unsafe { ++ *infop = core::mem::zeroed(); ++ } + if pid == 0 { + return 0; + } @@ -139,7 +164,11 @@ index 11f4bf2c..23e1a356 100644 + (*infop).si_status = crate::header::signal::SIGCONT as c_int; + } else { + (*infop).si_status = wtermsig(status); -+ (*infop).si_code = if wcoredump(status) { CLD_DUMPED } else { CLD_KILLED }; ++ (*infop).si_code = if wcoredump(status) { ++ CLD_DUMPED ++ } else { ++ CLD_KILLED ++ }; + } + } + @@ -148,3 +177,69 @@ index 11f4bf2c..23e1a356 100644 /// See . #[unsafe(no_mangle)] +diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk +--- a/tests/Makefile.tests.mk ++++ b/tests/Makefile.tests.mk +@@ -312,6 +312,7 @@ + grp/getgrgid_r \ + grp/getgrnam_r \ + grp/gr_iter \ ++ waitid \ + waitpid \ + waitpid_multiple \ + $(FAILING_TESTS) +diff --git a/tests/waitid.c b/tests/waitid.c +new file mode 100644 +--- /dev/null ++++ b/tests/waitid.c +@@ -0,0 +1,50 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include "test_helpers.h" ++ ++static void wait_until_child_exits(pid_t pid) { ++ siginfo_t info; ++ for (int i = 0; i < 50; ++i) { ++ info.si_pid = 0; ++ int ret = waitid(P_PID, pid, &info, WEXITED | WNOHANG | WNOWAIT); ++ ERROR_IF(waitid, ret, == -1); ++ if (info.si_pid == pid) { ++ assert(info.si_code == CLD_EXITED); ++ assert(info.si_status == 42); ++ return; ++ } ++ usleep(10000); ++ } ++ assert(!"waitid never observed child exit"); ++} ++ ++int main(void) { ++ pid_t pid = fork(); ++ ERROR_IF(fork, pid, == -1); ++ ++ if (pid == 0) { ++ usleep(50000); ++ _Exit(42); ++ } ++ ++ siginfo_t info; ++ info.si_pid = 0; ++ int ret = waitid(P_PID, pid, &info, WEXITED | WNOHANG | WNOWAIT); ++ ERROR_IF(waitid, ret, == -1); ++ assert(info.si_pid == 0); ++ ++ wait_until_child_exits(pid); ++ ++ int status = 0; ++ pid_t waited = waitpid(pid, &status, 0); ++ ERROR_IF(waitpid, waited, == -1); ++ assert(waited == pid); ++ assert(WIFEXITED(status)); ++ assert(WEXITSTATUS(status) == 42); ++ ++ return EXIT_SUCCESS; ++} diff --git a/recipes/core/AGENTS.md b/recipes/core/AGENTS.md index c1141d51..a2f6fe79 100644 --- a/recipes/core/AGENTS.md +++ b/recipes/core/AGENTS.md @@ -68,12 +68,12 @@ Driver access pattern: | Missing API | Location to implement | |-------------|----------------------| -| signalfd/signalfd4 | `relibc/source/src/header/signal/` — now source-visible in the current Red Bear tree | -| timerfd_create/settime/gettime | `relibc/source/src/header/sys_timerfd/` — now source-visible in the current Red Bear tree | -| eventfd | `relibc/source/src/header/sys_eventfd/` — now source-visible in the current Red Bear tree | -| F_DUPFD_CLOEXEC | `relibc/source/src/header/fcntl/` — now source-visible in the current Red Bear tree | -| MSG_CMSG_CLOEXEC, MSG_NOSIGNAL | `relibc/source/src/header/sys_socket/` — now source-visible in the current Red Bear tree | -| open_memstream | `relibc/source/src/header/stdio/` — now source-visible in the current Red Bear tree | +| signalfd/signalfd4 | `relibc/source/src/header/signal/` + active `local/patches/relibc/P3-signalfd*.patch` carriers — current support is recipe-applied, not plain-source convergence | +| timerfd_create/settime/gettime | `relibc/source/src/header/sys_timerfd/` + active `local/patches/relibc/P3-timerfd.patch` carrier — current support is recipe-applied | +| eventfd | `relibc/source/src/header/sys_eventfd/` + active `local/patches/relibc/P3-eventfd.patch` carrier — current support is recipe-applied | +| F_DUPFD_CLOEXEC | `relibc/source/src/header/fcntl/` + `local/patches/relibc/redox.patch` — support language should remain evidence-qualified | +| MSG_CMSG_CLOEXEC, MSG_NOSIGNAL | `relibc/source/src/header/sys_socket/` — support language should remain evidence-qualified | +| open_memstream | `relibc/source/src/header/stdio/` + `local/patches/relibc/P3-open-memstream.patch` carrier — current support is patch-carried | The current relibc work is therefore no longer just “add the missing Wayland APIs.” The higher-value remaining work is completeness depth, downstream cleanup, and runtime validation. diff --git a/recipes/core/relibc/recipe.toml b/recipes/core/relibc/recipe.toml index 8c945ffa..aa5b2f2b 100644 --- a/recipes/core/relibc/recipe.toml +++ b/recipes/core/relibc/recipe.toml @@ -7,20 +7,24 @@ patches = [ "../../../local/patches/relibc/P3-signalfd.patch", "../../../local/patches/relibc/P3-signalfd-header.patch", "../../../local/patches/relibc/P3-timerfd.patch", + "../../../local/patches/relibc/P3-waitid.patch", + "../../../local/patches/relibc/P3-semaphore-fixes.patch", + "../../../local/patches/relibc/P3-socket-cred.patch", "../../../local/patches/relibc/P3-elf64-types.patch", + "../../../local/patches/relibc/P3-open-memstream.patch", + "../../../local/patches/relibc/P3-ifaddrs-net_if.patch", + "../../../local/patches/relibc/P3-fd-event-tests.patch", ] [build] template = "custom" script = """ # rustup workaround https://github.com/rust-lang/rustup/issues/988 -if [ "${COOKBOOK_HOST_SYSROOT}" = "/usr" ]; then -if command -v rustup >/dev/null 2>&1; then +if [ "${COOKBOOK_HOST_SYSROOT}" = "/usr" ] && command -v rustup >/dev/null 2>&1; then pushd ${COOKBOOK_SOURCE} ${RUSTUP:-rustup} install popd fi -fi export CARGO=${CARGO:-env -u CARGO cargo} "${COOKBOOK_MAKE}" \ diff --git a/recipes/tests/relibc-tests-bins/recipe.toml b/recipes/tests/relibc-tests-bins/recipe.toml index 45a319ea..9837093b 100644 --- a/recipes/tests/relibc-tests-bins/recipe.toml +++ b/recipes/tests/relibc-tests-bins/recipe.toml @@ -9,6 +9,16 @@ git -C "${COOKBOOK_SOURCE}" archive --format=tar HEAD | tar -xf - rsync -av "${COOKBOOK_SOURCE}/openlibm/" ./openlibm/ patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/redox.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-eventfd.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-signalfd.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-signalfd-header.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-timerfd.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-waitid.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-semaphore-fixes.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-socket-cred.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-open-memstream.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-ifaddrs-net_if.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-fd-event-tests.patch" make headers TARGET="${TARGET}" diff --git a/recipes/tests/relibc-tests/recipe.toml b/recipes/tests/relibc-tests/recipe.toml index 9144441d..023eae75 100644 --- a/recipes/tests/relibc-tests/recipe.toml +++ b/recipes/tests/relibc-tests/recipe.toml @@ -11,6 +11,16 @@ git -C "${COOKBOOK_SOURCE}" archive --format=tar HEAD | tar -xf - rsync -av "${COOKBOOK_SOURCE}/openlibm/" ./openlibm/ patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/redox.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-eventfd.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-signalfd.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-signalfd-header.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-timerfd.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-waitid.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-semaphore-fixes.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-socket-cred.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-open-memstream.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-ifaddrs-net_if.patch" +patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/P3-fd-event-tests.patch" make headers TARGET="${TARGET}"