Refine relibc overlay patches and test wiring

This commit is contained in:
2026-04-20 18:37:35 +01:00
parent 6343f173c9
commit 3c88e91789
13 changed files with 938 additions and 179 deletions
@@ -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
+2 -1
View File
@@ -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;
+22 -26
View File
@@ -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 <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
@@ -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 \
@@ -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 \
waitid \
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)
+83 -32
View File
@@ -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::<sockaddr_in>() } else { 0 };
+ let netmask_size = if entry.netmask.is_some() { core::mem::size_of::<sockaddr_in>() } else { 0 };
+ let total = core::mem::size_of::<ifaddrs>() + name_len + addr_size + netmask_size;
+ let addr_align = core::mem::align_of::<sockaddr_in>();
+ let mut total = core::mem::size_of::<ifaddrs>() + 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::<sockaddr_in>();
+ unsafe { ptr.write(ipv4_addr(addr)) };
+ cursor = unsafe { cursor.add(core::mem::size_of::<sockaddr_in>()) };
@@ -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::<sockaddr_in>();
+ unsafe { ptr.write(ipv4_addr(netmask)) };
+ ptr.cast::<sockaddr>()
@@ -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::<c_char>(),
- },
-];
+fn interface_nameindex_table() -> [if_nameindex; 3] {
+ let entries = interface_entries();
+ [
+const INTERFACES: [if_nameindex; 3] = [
+ if_nameindex {
+ if_index: entries[0].index,
+ if_name: entries[0].name.as_ptr(),
+ if_index: 1,
+ if_name: (c"loopback").as_ptr(),
+ },
+ if_nameindex {
+ if_index: entries[1].index,
+ if_name: entries[1].name.as_ptr(),
+ if_index: 2,
+ if_name: (c"eth0").as_ptr(),
+ },
+ if_nameindex {
+ if_index: 0,
+ if_name: null::<c_char>(),
+ },
+ ]
+}
+];
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_freenameindex.html>.
///
@@ -215,26 +227,8 @@ index edbfedec..bd07e2c9 100644
}
ERRNO.set(ENXIO);
null::<c_char>()
@@ -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::<if_nameindex>(&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::<if_nameindex>(&TABLE[0])
+ }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_nametoindex.html>.
@@ -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 <assert.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <stdio.h>
+#include <string.h>
+
+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;
+}
@@ -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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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;
+}
@@ -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<&timespec>, clock_id: clockid_t) -> Result<(), ()> {
+ pub fn wait(&self, timeout_opt: Option<&timespec>, 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 <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/semaphore.h.html>.
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 <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/semaphore.h.html>.
// 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::<NamedSemaphore>() 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::<NamedSemaphore>();
+ if created {
+ unsafe {
+ named.write(NamedSemaphore {
+ sem: RlctSempahore::new(value),
+ });
+ }
+ }
+
+ Ok(named.cast())
+}
+
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_close.html>.
-// #[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::<c_void>(), mem::size_of::<NamedSemaphore>()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_destroy.html>.
@@ -51,12 +139,25 @@
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_open.html>.
// 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::<mode_t>() }, unsafe { args.arg::<c_uint>() })
+ } 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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_post.html>.
@@ -70,23 +171,27 @@
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_trywait.html>.
#[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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_unlink.html>.
-// #[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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_trywait.html>.
#[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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_clockwait.html>.
@@ -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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_timedwait.html>.
#[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 <bits/timespec.h> // 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 <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <time.h>
+#include <unistd.h>
+
+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 <assert.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+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;
+}
+16 -60
View File
@@ -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;
+}
+178
View File
@@ -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::<ucred>() 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::<ucred>() {
+ 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 <assert.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#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 <assert.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#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;
+}
+111 -16
View File
@@ -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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html>.
#[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 <https://pubs.opengroup.org/onlinepubs/9799919799/functions/waitpid.html>.
#[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 <assert.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#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;
+}
+6 -6
View File
@@ -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.
+7 -3
View File
@@ -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}" \
@@ -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}"
+10
View File
@@ -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}"