Refine relibc overlay patches and test wiring
This commit is contained in:
@@ -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
|
diff --git a/src/header/stdlib/cbindgen.toml b/src/header/stdlib/cbindgen.toml
|
||||||
index 2e02e68a..c2643c49 100644
|
|
||||||
--- a/src/header/stdlib/cbindgen.toml
|
--- a/src/header/stdlib/cbindgen.toml
|
||||||
+++ b/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"]
|
sys_includes = ["stddef.h", "alloca.h", "wchar.h", "features.h"]
|
||||||
include_guard = "_RELIBC_STDLIB_H"
|
include_guard = "_RELIBC_STDLIB_H"
|
||||||
-trailer = """
|
-trailer = """
|
||||||
-#ifndef _RELIBC_STDLIB_STRTOLD_H
|
-#ifndef _RELIBC_STDLIB_EXTRA_H
|
||||||
-#define _RELIBC_STDLIB_STRTOLD_H
|
-#define _RELIBC_STDLIB_EXTRA_H
|
||||||
-
|
-
|
||||||
-#ifdef __cplusplus
|
-#ifdef __cplusplus
|
||||||
-extern \"C\" {
|
-extern "C" {
|
||||||
-#endif
|
-#endif
|
||||||
-
|
-
|
||||||
-long double strtold(const char *nptr, char **endptr);
|
-long double strtold(const char *nptr, char **endptr);
|
||||||
@@ -41,3 +22,4 @@ index 2e02e68a..c2643c49 100644
|
|||||||
-"""
|
-"""
|
||||||
language = "C"
|
language = "C"
|
||||||
style = "Type"
|
style = "Type"
|
||||||
|
no_includes = true
|
||||||
|
|||||||
@@ -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
|
--- a/src/header/elf/mod.rs
|
||||||
+++ b/src/header/elf/mod.rs
|
+++ b/src/header/elf/mod.rs
|
||||||
@@ -9,8 +9,8 @@
|
@@ -9,8 +9,8 @@
|
||||||
|
|
||||||
pub type Elf32_Word = uint32_t;
|
pub type Elf32_Word = uint32_t;
|
||||||
pub type Elf32_Sword = int32_t;
|
pub type Elf32_Sword = int32_t;
|
||||||
-pub type Elf64_Word = uint64_t;
|
-pub type Elf64_Word = uint64_t;
|
||||||
|
|||||||
@@ -58,6 +58,23 @@ new file mode 100644
|
|||||||
+ puts("signalfd ok");
|
+ puts("signalfd ok");
|
||||||
+ return 0;
|
+ 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
|
diff --git a/tests/sys_timerfd/timerfd.c b/tests/sys_timerfd/timerfd.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
@@ -95,36 +112,15 @@ new file mode 100644
|
|||||||
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
|
||||||
@@ -312,6 +312,9 @@ VARIED_NAMES=\
|
@@ -314,8 +314,12 @@ VARIED_NAMES=\
|
||||||
grp/getgrgid_r \
|
grp/gr_iter \
|
||||||
grp/getgrnam_r \
|
semaphore/named \
|
||||||
grp/gr_iter \
|
semaphore/unnamed \
|
||||||
+ sys_eventfd/eventfd \
|
+ sys_eventfd/eventfd \
|
||||||
|
+ sys_signalfd/header_only \
|
||||||
+ sys_signalfd/signalfd \
|
+ sys_signalfd/signalfd \
|
||||||
+ sys_timerfd/timerfd \
|
+ sys_timerfd/timerfd \
|
||||||
waitpid \
|
waitid \
|
||||||
waitpid_multiple \
|
waitpid \
|
||||||
$(FAILING_TESTS)
|
waitpid_multiple \
|
||||||
diff --git a/tests/Makefile b/tests/Makefile
|
$(FAILING_TESTS)
|
||||||
--- 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)
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ index bddb69b8..598beba3 100644
|
|||||||
platform::{
|
platform::{
|
||||||
self,
|
self,
|
||||||
types::{c_char, c_int, c_uint, c_void},
|
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,
|
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 {
|
+unsafe fn make_ifaddrs_node(entry: &crate::header::net_if::InterfaceEntry) -> *mut ifaddrs {
|
||||||
+ let name_len = entry.name.to_bytes_with_nul().len();
|
+ 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 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 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;
|
+ let raw = unsafe { stdlib::malloc(total) } as *mut u8;
|
||||||
+ if raw.is_null() {
|
+ if raw.is_null() {
|
||||||
+ return core::ptr::null_mut();
|
+ return core::ptr::null_mut();
|
||||||
@@ -52,6 +63,8 @@ index bddb69b8..598beba3 100644
|
|||||||
+ cursor = unsafe { cursor.add(name_len) };
|
+ cursor = unsafe { cursor.add(name_len) };
|
||||||
+
|
+
|
||||||
+ let addr_ptr = if let Some(addr) = entry.addr {
|
+ 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>();
|
+ let ptr = cursor.cast::<sockaddr_in>();
|
||||||
+ unsafe { ptr.write(ipv4_addr(addr)) };
|
+ unsafe { ptr.write(ipv4_addr(addr)) };
|
||||||
+ cursor = unsafe { cursor.add(core::mem::size_of::<sockaddr_in>()) };
|
+ 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 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>();
|
+ let ptr = cursor.cast::<sockaddr_in>();
|
||||||
+ unsafe { ptr.write(ipv4_addr(netmask)) };
|
+ unsafe { ptr.write(ipv4_addr(netmask)) };
|
||||||
+ ptr.cast::<sockaddr>()
|
+ 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
|
index edbfedec..bd07e2c9 100644
|
||||||
--- a/src/header/net_if/mod.rs
|
--- a/src/header/net_if/mod.rs
|
||||||
+++ b/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,
|
if_name: *const c_char,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,23 +186,20 @@ index edbfedec..bd07e2c9 100644
|
|||||||
- if_name: null::<c_char>(),
|
- if_name: null::<c_char>(),
|
||||||
- },
|
- },
|
||||||
-];
|
-];
|
||||||
+fn interface_nameindex_table() -> [if_nameindex; 3] {
|
+const INTERFACES: [if_nameindex; 3] = [
|
||||||
+ let entries = interface_entries();
|
+ if_nameindex {
|
||||||
+ [
|
+ if_index: 1,
|
||||||
+ if_nameindex {
|
+ if_name: (c"loopback").as_ptr(),
|
||||||
+ if_index: entries[0].index,
|
+ },
|
||||||
+ if_name: entries[0].name.as_ptr(),
|
+ if_nameindex {
|
||||||
+ },
|
+ if_index: 2,
|
||||||
+ if_nameindex {
|
+ if_name: (c"eth0").as_ptr(),
|
||||||
+ if_index: entries[1].index,
|
+ },
|
||||||
+ if_name: entries[1].name.as_ptr(),
|
+ if_nameindex {
|
||||||
+ },
|
+ if_index: 0,
|
||||||
+ if_nameindex {
|
+ if_name: null::<c_char>(),
|
||||||
+ if_index: 0,
|
+ },
|
||||||
+ if_name: null::<c_char>(),
|
+];
|
||||||
+ },
|
|
||||||
+ ]
|
|
||||||
+}
|
|
||||||
|
|
||||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_freenameindex.html>.
|
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_freenameindex.html>.
|
||||||
///
|
///
|
||||||
@@ -215,26 +227,8 @@ index edbfedec..bd07e2c9 100644
|
|||||||
}
|
}
|
||||||
ERRNO.set(ENXIO);
|
ERRNO.set(ENXIO);
|
||||||
null::<c_char>()
|
null::<c_char>()
|
||||||
@@ -66,7 +112,17 @@ pub unsafe extern "C" fn if_indextoname(idx: c_uint, buf: *mut c_char) -> *const
|
@@ -78,9 +136,12 @@ pub unsafe extern "C" fn if_nametoindex(name: *const c_char) -> c_uint {
|
||||||
/// The end of the list is determined by an if_nameindex struct having if_index 0 and if_name NULL
|
if name.is_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 {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
let name = unsafe { CStr::from_ptr(name).to_str().unwrap_or("") };
|
let name = unsafe { CStr::from_ptr(name).to_str().unwrap_or("") };
|
||||||
@@ -248,3 +242,60 @@ index edbfedec..bd07e2c9 100644
|
|||||||
}
|
}
|
||||||
0
|
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 {
|
+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()
|
+ 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<×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 <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;
|
||||||
|
+}
|
||||||
@@ -1,18 +1,10 @@
|
|||||||
diff -ruN a/src/header/mod.rs b/src/header/mod.rs
|
diff --git a/src/header/mod.rs b/src/header/mod.rs
|
||||||
--- a/src/header/mod.rs 2026-04-15 09:48:02.257700000 +0100
|
diff --git a/src/header/sys_signalfd/cbindgen.toml b/src/header/sys_signalfd/cbindgen.toml
|
||||||
+++ b/src/header/mod.rs 2026-04-19 13:30:00.000000000 +0100
|
new file mode 100644
|
||||||
@@ -98,6 +98,7 @@
|
--- /dev/null
|
||||||
pub mod sys_resource;
|
+++ b/src/header/sys_signalfd/cbindgen.toml
|
||||||
pub mod sys_select;
|
@@ -0,0 +1,24 @@
|
||||||
+pub mod sys_signalfd;
|
+sys_includes = ["signal.h", "stdint.h", "stddef.h"]
|
||||||
// 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"]
|
|
||||||
+include_guard = "_SYS_SIGNALFD_H"
|
+include_guard = "_SYS_SIGNALFD_H"
|
||||||
+trailer = """
|
+trailer = """
|
||||||
+#ifndef SFD_CLOEXEC
|
+#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
|
+#define SFD_NONBLOCK 0x800
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+struct signalfd_siginfo {
|
+int signalfd(int fd, const sigset_t *mask, size_t masksize);
|
||||||
+ uint32_t ssi_signo;
|
+int signalfd4(int fd, const sigset_t *mask, size_t masksize, int flags);
|
||||||
+ 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];
|
|
||||||
+};
|
|
||||||
+"""
|
+"""
|
||||||
+language = "C"
|
+language = "C"
|
||||||
+style = "Tag"
|
+style = "Tag"
|
||||||
+no_includes = true
|
+no_includes = true
|
||||||
+cpp_compat = true
|
+cpp_compat = true
|
||||||
|
+
|
||||||
+[enum]
|
+[enum]
|
||||||
+prefix_with_name = true
|
+prefix_with_name = true
|
||||||
|
+
|
||||||
+[export.rename]
|
+[export.rename]
|
||||||
+"signalfd_siginfo" = "struct signalfd_siginfo"
|
+"signalfd_siginfo" = "struct signalfd_siginfo"
|
||||||
diff -ruN a/src/header/sys_signalfd/mod.rs b/src/header/sys_signalfd/mod.rs
|
diff --git 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
|
new file mode 100644
|
||||||
+++ b/src/header/sys_signalfd/mod.rs 2026-04-15 09:48:02.257778048 +0100
|
--- /dev/null
|
||||||
@@ -0,0 +1,29 @@
|
+++ b/src/header/sys_signalfd/mod.rs
|
||||||
|
@@ -0,0 +1,14 @@
|
||||||
+//! `sys/signalfd.h` implementation.
|
+//! `sys/signalfd.h` implementation.
|
||||||
+
|
+
|
||||||
+use crate::{
|
+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;
|
+pub const SFD_NONBLOCK: c_int = signal::SFD_NONBLOCK;
|
||||||
+
|
+
|
||||||
+#[unsafe(no_mangle)]
|
+#[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) {
|
+pub extern "C" fn _cbindgen_export_sys_signalfd_siginfo(siginfo: signalfd_siginfo) {
|
||||||
+ let _ = siginfo;
|
+ let _ = siginfo;
|
||||||
+}
|
+}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
+}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
diff --git a/src/header/sys_wait/mod.rs b/src/header/sys_wait/mod.rs
|
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
|
--- a/src/header/sys_wait/mod.rs
|
||||||
+++ b/src/header/sys_wait/mod.rs
|
+++ b/src/header/sys_wait/mod.rs
|
||||||
@@ -4,13 +4,17 @@
|
@@ -4,12 +4,16 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::ResultExt,
|
error::ResultExt,
|
||||||
@@ -15,14 +14,13 @@ index 11f4bf2c..23e1a356 100644
|
|||||||
+ types::{c_int, c_uint, pid_t},
|
+ types::{c_int, c_uint, pid_t},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
+
|
||||||
+pub type idtype_t = c_int;
|
+pub type idtype_t = c_int;
|
||||||
+pub type id_t = c_uint;
|
+pub type id_t = c_uint;
|
||||||
+
|
|
||||||
pub const WNOHANG: c_int = 1;
|
pub const WNOHANG: c_int = 1;
|
||||||
pub const WUNTRACED: c_int = 2;
|
pub const WUNTRACED: c_int = 2;
|
||||||
|
@@ -24,25 +28,143 @@
|
||||||
@@ -24,25 +28,112 @@ pub const __WALL: c_int = 0x4000_0000;
|
|
||||||
#[allow(overflowing_literals)]
|
#[allow(overflowing_literals)]
|
||||||
pub const __WCLONE: c_int = 0x8000_0000;
|
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_STOPPED: c_int = 5;
|
||||||
+pub const CLD_CONTINUED: c_int = 6;
|
+pub const CLD_CONTINUED: c_int = 6;
|
||||||
+
|
+
|
||||||
+fn wexitstatus(status: c_int) -> c_int { (status >> 8) & 0xff }
|
+fn wexitstatus(status: c_int) -> c_int {
|
||||||
+fn wtermsig(status: c_int) -> c_int { status & 0x7f }
|
+ (status >> 8) & 0xff
|
||||||
+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 wtermsig(status: c_int) -> c_int {
|
||||||
+fn wifstopped(status: c_int) -> bool { (status & 0xff) == 0x7f }
|
+ status & 0x7f
|
||||||
+fn wifcontinued(status: c_int) -> bool { status == 0xffff }
|
+}
|
||||||
|
+
|
||||||
|
+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>.
|
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html>.
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
@@ -89,6 +107,10 @@ index 11f4bf2c..23e1a356 100644
|
|||||||
+ if options & WCONTINUED != 0 {
|
+ if options & WCONTINUED != 0 {
|
||||||
+ waitpid_options |= WCONTINUED;
|
+ waitpid_options |= WCONTINUED;
|
||||||
+ }
|
+ }
|
||||||
|
+ if options & WNOWAIT != 0 {
|
||||||
|
+ waitpid_options |= WNOWAIT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ Some(waitpid_options)
|
+ Some(waitpid_options)
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
@@ -114,12 +136,15 @@ index 11f4bf2c..23e1a356 100644
|
|||||||
+ };
|
+ };
|
||||||
+
|
+
|
||||||
+ let mut status = 0;
|
+ 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 {
|
+ if pid < 0 {
|
||||||
+ return -1;
|
+ return -1;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ unsafe { *infop = core::mem::zeroed() };
|
+ unsafe {
|
||||||
|
+ *infop = core::mem::zeroed();
|
||||||
|
+ }
|
||||||
+ if pid == 0 {
|
+ if pid == 0 {
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+ }
|
+ }
|
||||||
@@ -139,7 +164,11 @@ index 11f4bf2c..23e1a356 100644
|
|||||||
+ (*infop).si_status = crate::header::signal::SIGCONT as c_int;
|
+ (*infop).si_status = crate::header::signal::SIGCONT as c_int;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ (*infop).si_status = wtermsig(status);
|
+ (*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>.
|
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/waitpid.html>.
|
||||||
#[unsafe(no_mangle)]
|
#[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;
|
||||||
|
+}
|
||||||
|
|||||||
@@ -68,12 +68,12 @@ Driver access pattern:
|
|||||||
|
|
||||||
| Missing API | Location to implement |
|
| Missing API | Location to implement |
|
||||||
|-------------|----------------------|
|
|-------------|----------------------|
|
||||||
| signalfd/signalfd4 | `relibc/source/src/header/signal/` — 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/` — now source-visible in the current Red Bear tree |
|
| 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/` — now source-visible in the current Red Bear tree |
|
| 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/` — now source-visible in the current Red Bear tree |
|
| 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/` — now source-visible in the current Red Bear tree |
|
| MSG_CMSG_CLOEXEC, MSG_NOSIGNAL | `relibc/source/src/header/sys_socket/` — support language should remain evidence-qualified |
|
||||||
| open_memstream | `relibc/source/src/header/stdio/` — now source-visible in the current Red Bear tree |
|
| 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
|
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.
|
remaining work is completeness depth, downstream cleanup, and runtime validation.
|
||||||
|
|||||||
@@ -7,20 +7,24 @@ patches = [
|
|||||||
"../../../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",
|
||||||
|
"../../../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-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]
|
[build]
|
||||||
template = "custom"
|
template = "custom"
|
||||||
script = """
|
script = """
|
||||||
# rustup workaround https://github.com/rust-lang/rustup/issues/988
|
# rustup workaround https://github.com/rust-lang/rustup/issues/988
|
||||||
if [ "${COOKBOOK_HOST_SYSROOT}" = "/usr" ]; then
|
if [ "${COOKBOOK_HOST_SYSROOT}" = "/usr" ] && command -v rustup >/dev/null 2>&1; then
|
||||||
if command -v rustup >/dev/null 2>&1; then
|
|
||||||
pushd ${COOKBOOK_SOURCE}
|
pushd ${COOKBOOK_SOURCE}
|
||||||
${RUSTUP:-rustup} install
|
${RUSTUP:-rustup} install
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
export CARGO=${CARGO:-env -u CARGO cargo}
|
export CARGO=${CARGO:-env -u CARGO cargo}
|
||||||
"${COOKBOOK_MAKE}" \
|
"${COOKBOOK_MAKE}" \
|
||||||
|
|||||||
@@ -9,6 +9,16 @@ git -C "${COOKBOOK_SOURCE}" archive --format=tar HEAD | tar -xf -
|
|||||||
rsync -av "${COOKBOOK_SOURCE}/openlibm/" ./openlibm/
|
rsync -av "${COOKBOOK_SOURCE}/openlibm/" ./openlibm/
|
||||||
|
|
||||||
patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/redox.patch"
|
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}"
|
make headers TARGET="${TARGET}"
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,16 @@ git -C "${COOKBOOK_SOURCE}" archive --format=tar HEAD | tar -xf -
|
|||||||
rsync -av "${COOKBOOK_SOURCE}/openlibm/" ./openlibm/
|
rsync -av "${COOKBOOK_SOURCE}/openlibm/" ./openlibm/
|
||||||
|
|
||||||
patch -N -p1 < "${COOKBOOK_ROOT}/local/patches/relibc/redox.patch"
|
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}"
|
make headers TARGET="${TARGET}"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user