Consolidate relibc overlay patch chain
Keep the relibc compatibility work in tracked local patch carriers and align the recipe with the full durable patch stack so clean reapply and rebuild paths stay reproducible. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
diff --git a/src/header/ifaddrs/mod.rs b/src/header/ifaddrs/mod.rs
|
||||
index bddb69b8..598beba3 100644
|
||||
--- a/src/header/ifaddrs/mod.rs
|
||||
+++ b/src/header/ifaddrs/mod.rs
|
||||
@@ -3,7 +3,13 @@
|
||||
//! Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/getifaddrs.3.html>.
|
||||
|
||||
use crate::{
|
||||
- header::{errno, stdlib, sys_socket::sockaddr},
|
||||
+ header::{
|
||||
+ errno,
|
||||
+ net_if::interface_entries,
|
||||
+ netinet_in::{in_addr, sockaddr_in},
|
||||
+ stdlib,
|
||||
+ sys_socket::{constants::AF_INET, sockaddr},
|
||||
+ },
|
||||
platform::{
|
||||
self,
|
||||
types::{c_char, c_int, c_uint, c_void},
|
||||
@@ -27,6 +33,68 @@ pub struct ifaddrs {
|
||||
ifa_data: *mut c_void,
|
||||
}
|
||||
|
||||
+fn ipv4_addr(bytes: [u8; 4]) -> sockaddr_in {
|
||||
+ sockaddr_in {
|
||||
+ sin_family: AF_INET as _,
|
||||
+ sin_port: 0,
|
||||
+ sin_addr: in_addr {
|
||||
+ s_addr: u32::from_ne_bytes(bytes),
|
||||
+ },
|
||||
+ sin_zero: [0; 8],
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+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 raw = unsafe { stdlib::malloc(total) } as *mut u8;
|
||||
+ if raw.is_null() {
|
||||
+ return core::ptr::null_mut();
|
||||
+ }
|
||||
+
|
||||
+ unsafe { raw.write_bytes(0, total) };
|
||||
+
|
||||
+ let node = raw.cast::<ifaddrs>();
|
||||
+ let mut cursor = unsafe { raw.add(core::mem::size_of::<ifaddrs>()) };
|
||||
+
|
||||
+ let name_ptr = cursor.cast::<c_char>();
|
||||
+ unsafe { core::ptr::copy_nonoverlapping(entry.name.as_ptr(), name_ptr, name_len) };
|
||||
+ cursor = unsafe { cursor.add(name_len) };
|
||||
+
|
||||
+ let addr_ptr = if let Some(addr) = entry.addr {
|
||||
+ let ptr = cursor.cast::<sockaddr_in>();
|
||||
+ unsafe { ptr.write(ipv4_addr(addr)) };
|
||||
+ cursor = unsafe { cursor.add(core::mem::size_of::<sockaddr_in>()) };
|
||||
+ ptr.cast::<sockaddr>()
|
||||
+ } else {
|
||||
+ core::ptr::null_mut()
|
||||
+ };
|
||||
+
|
||||
+ let netmask_ptr = if let Some(netmask) = entry.netmask {
|
||||
+ let ptr = cursor.cast::<sockaddr_in>();
|
||||
+ unsafe { ptr.write(ipv4_addr(netmask)) };
|
||||
+ ptr.cast::<sockaddr>()
|
||||
+ } else {
|
||||
+ core::ptr::null_mut()
|
||||
+ };
|
||||
+
|
||||
+ unsafe {
|
||||
+ node.write(ifaddrs {
|
||||
+ ifa_next: core::ptr::null_mut(),
|
||||
+ ifa_name: name_ptr,
|
||||
+ ifa_flags: entry.flags,
|
||||
+ ifa_addr: addr_ptr,
|
||||
+ ifa_netmask: netmask_ptr,
|
||||
+ ifa_ifu: ifaddrs_ifa_ifu { ifu_broadaddr: core::ptr::null_mut() },
|
||||
+ ifa_data: core::ptr::null_mut(),
|
||||
+ })
|
||||
+ };
|
||||
+
|
||||
+ node
|
||||
+}
|
||||
+
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn freeifaddrs(mut ifa: *mut ifaddrs) {
|
||||
while !ifa.is_null() {
|
||||
@@ -38,7 +106,31 @@ pub unsafe extern "C" fn freeifaddrs(mut ifa: *mut ifaddrs) {
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn getifaddrs(ifap: *mut *mut ifaddrs) -> c_int {
|
||||
- //TODO: implement getifaddrs
|
||||
- platform::ERRNO.set(errno::ENOSYS);
|
||||
- -1
|
||||
+ if ifap.is_null() {
|
||||
+ platform::ERRNO.set(errno::EFAULT);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ let entries = interface_entries();
|
||||
+ let mut head = core::ptr::null_mut();
|
||||
+ let mut prev: *mut ifaddrs = core::ptr::null_mut();
|
||||
+
|
||||
+ for entry in &entries {
|
||||
+ let node = unsafe { make_ifaddrs_node(entry) };
|
||||
+ if node.is_null() {
|
||||
+ unsafe { freeifaddrs(head) };
|
||||
+ platform::ERRNO.set(errno::ENOMEM);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if head.is_null() {
|
||||
+ head = node;
|
||||
+ } else {
|
||||
+ unsafe { (*prev).ifa_next = node };
|
||||
+ }
|
||||
+ prev = node;
|
||||
+ }
|
||||
+
|
||||
+ unsafe { *ifap = head };
|
||||
+ 0
|
||||
}
|
||||
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 {
|
||||
if_name: *const c_char,
|
||||
}
|
||||
|
||||
+#[derive(Clone)]
|
||||
+pub(crate) struct InterfaceEntry {
|
||||
+ pub index: c_uint,
|
||||
+ pub name: CStr<'static>,
|
||||
+ pub flags: c_uint,
|
||||
+ pub addr: Option<[u8; 4]>,
|
||||
+ pub netmask: Option<[u8; 4]>,
|
||||
+}
|
||||
+
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/net_if.h.html>.
|
||||
pub const IF_NAMESIZE: usize = 16;
|
||||
|
||||
-const IF_STUB_INTERFACE: *const c_char = (c"stub").as_ptr();
|
||||
+pub(crate) fn interface_entries() -> [InterfaceEntry; 2] {
|
||||
+ [
|
||||
+ InterfaceEntry {
|
||||
+ index: 1,
|
||||
+ name: c"loopback".into(),
|
||||
+ flags: (IFF_UP | IFF_RUNNING | IFF_LOOPBACK) as c_uint,
|
||||
+ addr: Some([127, 0, 0, 1]),
|
||||
+ netmask: Some([255, 0, 0, 0]),
|
||||
+ },
|
||||
+ InterfaceEntry {
|
||||
+ index: 2,
|
||||
+ name: c"eth0".into(),
|
||||
+ flags: (IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST) as c_uint,
|
||||
+ addr: None,
|
||||
+ netmask: None,
|
||||
+ },
|
||||
+ ]
|
||||
+}
|
||||
|
||||
-const INTERFACES: &[if_nameindex] = &[
|
||||
- if_nameindex {
|
||||
- if_index: 1,
|
||||
- if_name: IF_STUB_INTERFACE,
|
||||
- },
|
||||
- if_nameindex {
|
||||
- if_index: 0,
|
||||
- if_name: null::<c_char>(),
|
||||
- },
|
||||
-];
|
||||
+fn interface_nameindex_table() -> [if_nameindex; 3] {
|
||||
+ let entries = interface_entries();
|
||||
+ [
|
||||
+ if_nameindex {
|
||||
+ if_index: entries[0].index,
|
||||
+ if_name: entries[0].name.as_ptr(),
|
||||
+ },
|
||||
+ if_nameindex {
|
||||
+ if_index: entries[1].index,
|
||||
+ if_name: entries[1].name.as_ptr(),
|
||||
+ },
|
||||
+ if_nameindex {
|
||||
+ if_index: 0,
|
||||
+ if_name: null::<c_char>(),
|
||||
+ },
|
||||
+ ]
|
||||
+}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_freenameindex.html>.
|
||||
///
|
||||
@@ -52,8 +85,21 @@ pub unsafe extern "C" fn if_freenameindex(s: *mut if_nameindex) {}
|
||||
/// Currently only checks against inteface index 1.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn if_indextoname(idx: c_uint, buf: *mut c_char) -> *const c_char {
|
||||
- if idx == 1 {
|
||||
- return IF_STUB_INTERFACE;
|
||||
+ let entries = interface_entries();
|
||||
+ for entry in &entries {
|
||||
+ if entry.index == idx {
|
||||
+ if !buf.is_null() {
|
||||
+ unsafe {
|
||||
+ core::ptr::copy_nonoverlapping(
|
||||
+ entry.name.as_ptr(),
|
||||
+ buf,
|
||||
+ entry.name.to_bytes_with_nul().len(),
|
||||
+ );
|
||||
+ }
|
||||
+ return buf;
|
||||
+ }
|
||||
+ return entry.name.as_ptr();
|
||||
+ }
|
||||
}
|
||||
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 {
|
||||
return 0;
|
||||
}
|
||||
let name = unsafe { CStr::from_ptr(name).to_str().unwrap_or("") };
|
||||
- if name.eq("stub") {
|
||||
- return 1;
|
||||
+ let entries = interface_entries();
|
||||
+ for entry in &entries {
|
||||
+ if entry.name.to_str().map(|entry_name| entry_name == name).unwrap_or(false) {
|
||||
+ return entry.index;
|
||||
+ }
|
||||
}
|
||||
0
|
||||
}
|
||||
@@ -1,14 +1,3 @@
|
||||
diff -ruN a/src/header/mod.rs b/src/header/mod.rs
|
||||
--- a/src/header/mod.rs 2026-04-15 09:40:30.417847129 +0100
|
||||
+++ b/src/header/mod.rs 2026-04-15 09:48:02.257729647 +0100
|
||||
@@ -103,6 +103,7 @@
|
||||
pub mod sys_stat;
|
||||
pub mod sys_statvfs;
|
||||
pub mod sys_time;
|
||||
+pub mod sys_signalfd;
|
||||
#[deprecated]
|
||||
pub mod sys_timeb;
|
||||
//pub mod sys_times;
|
||||
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
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
diff -ruN a/src/header/mod.rs b/src/header/mod.rs
|
||||
--- a/src/header/mod.rs 2026-04-15 09:58:03.811510680 +0100
|
||||
+++ b/src/header/mod.rs 2026-04-15 09:59:40.902089070 +0100
|
||||
@@ -103,6 +103,7 @@
|
||||
pub mod sys_stat;
|
||||
pub mod sys_statvfs;
|
||||
pub mod sys_time;
|
||||
+pub mod sys_timerfd;
|
||||
#[deprecated]
|
||||
pub mod sys_timeb;
|
||||
//pub mod sys_times;
|
||||
diff -ruN a/src/header/sys_timerfd/cbindgen.toml b/src/header/sys_timerfd/cbindgen.toml
|
||||
--- a/src/header/sys_timerfd/cbindgen.toml 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ b/src/header/sys_timerfd/cbindgen.toml 2026-04-15 09:59:40.902120449 +0100
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/src/header/sys_wait/mod.rs b/src/header/sys_wait/mod.rs
|
||||
index 11f4bf2c..91a58c5b 100644
|
||||
index 11f4bf2c..23e1a356 100644
|
||||
--- a/src/header/sys_wait/mod.rs
|
||||
+++ b/src/header/sys_wait/mod.rs
|
||||
@@ -4,13 +4,17 @@
|
||||
@@ -22,11 +22,10 @@ index 11f4bf2c..91a58c5b 100644
|
||||
pub const WNOHANG: c_int = 1;
|
||||
pub const WUNTRACED: c_int = 2;
|
||||
|
||||
@@ -24,27 +28,89 @@ pub const __WALL: c_int = 0x4000_0000;
|
||||
@@ -24,25 +28,112 @@ pub const __WALL: c_int = 0x4000_0000;
|
||||
#[allow(overflowing_literals)]
|
||||
pub const __WCLONE: c_int = 0x8000_0000;
|
||||
|
||||
-/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html>.
|
||||
+pub const P_ALL: idtype_t = 0;
|
||||
+pub const P_PID: idtype_t = 1;
|
||||
+pub const P_PGID: idtype_t = 2;
|
||||
@@ -46,6 +45,7 @@ index 11f4bf2c..91a58c5b 100644
|
||||
+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)]
|
||||
pub unsafe extern "C" fn wait(stat_loc: *mut c_int) -> pid_t {
|
||||
unsafe { waitpid(!0, stat_loc, 0) }
|
||||
@@ -64,8 +64,6 @@ index 11f4bf2c..91a58c5b 100644
|
||||
- * unimplemented!();
|
||||
- * }
|
||||
- */
|
||||
-
|
||||
-/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/waitpid.html>.
|
||||
+fn map_waitid_target(idtype: idtype_t, id: id_t) -> Option<pid_t> {
|
||||
+ match idtype {
|
||||
+ P_ALL => Some(-1),
|
||||
@@ -75,6 +73,25 @@ index 11f4bf2c..91a58c5b 100644
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+fn map_waitid_options(options: c_int) -> Option<c_int> {
|
||||
+ let interest = options & (WEXITED | WSTOPPED | WCONTINUED);
|
||||
+ if interest == 0 {
|
||||
+ return None;
|
||||
+ }
|
||||
+
|
||||
+ let mut waitpid_options = 0;
|
||||
+ if options & WNOHANG != 0 {
|
||||
+ waitpid_options |= WNOHANG;
|
||||
+ }
|
||||
+ if options & WSTOPPED != 0 {
|
||||
+ waitpid_options |= WUNTRACED;
|
||||
+ }
|
||||
+ if options & WCONTINUED != 0 {
|
||||
+ waitpid_options |= WCONTINUED;
|
||||
+ }
|
||||
+ Some(waitpid_options)
|
||||
+}
|
||||
+
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub unsafe extern "C" fn waitid(
|
||||
+ idtype: idtype_t,
|
||||
@@ -91,9 +108,13 @@ index 11f4bf2c..91a58c5b 100644
|
||||
+ ERRNO.set(crate::header::errno::EINVAL);
|
||||
+ return -1;
|
||||
+ };
|
||||
+ let Some(waitpid_options) = map_waitid_options(options) else {
|
||||
+ ERRNO.set(crate::header::errno::EINVAL);
|
||||
+ return -1;
|
||||
+ };
|
||||
+
|
||||
+ let mut status = 0;
|
||||
+ let pid = Sys::waitpid(pid_target, Some(Out::from_mut(&mut status)), 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;
|
||||
+ }
|
||||
@@ -124,7 +145,6 @@ index 11f4bf2c..91a58c5b 100644
|
||||
+
|
||||
+ 0
|
||||
+}
|
||||
+
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/waitpid.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
|
||||
Sys::waitpid(pid, unsafe { Out::nullable(stat_loc) }, options).or_minus_one_errno()
|
||||
|
||||
+196
-103
@@ -24,20 +24,25 @@ index 6a4db2fa..82484375 100644
|
||||
use crate::{
|
||||
c_str::CStr,
|
||||
error::ResultExt,
|
||||
+ header::unistd::{close, dup},
|
||||
+ header::unistd::close,
|
||||
platform::{
|
||||
Pal, Sys,
|
||||
types::{c_char, c_int, c_short, c_ulonglong, mode_t, off_t, pid_t},
|
||||
@@ -74,6 +75,18 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) ->
|
||||
@@ -74,5 +75,22 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) ->
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
+ if cmd == F_DUPFD_CLOEXEC {
|
||||
+ let new_fd = dup(fildes);
|
||||
+ let new_fd = Sys::fcntl(fildes, F_DUPFD_CLOEXEC, arg).or_minus_one_errno();
|
||||
+ if new_fd >= 0 {
|
||||
+ return new_fd;
|
||||
+ }
|
||||
+
|
||||
+ let new_fd = Sys::fcntl(fildes, F_DUPFD, arg).or_minus_one_errno();
|
||||
+ if new_fd < 0 {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if unsafe { fcntl(new_fd, F_SETFD, FD_CLOEXEC as c_ulonglong) } < 0 {
|
||||
+ if Sys::fcntl(new_fd, F_SETFD, FD_CLOEXEC as c_ulonglong).or_minus_one_errno() < 0 {
|
||||
+ let _ = close(new_fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
@@ -46,112 +51,200 @@ index 6a4db2fa..82484375 100644
|
||||
+
|
||||
Sys::fcntl(fildes, cmd, arg).or_minus_one_errno()
|
||||
}
|
||||
diff --git a/src/header/fcntl/linux.rs b/src/header/fcntl/linux.rs
|
||||
index 9a3978dc..906ad525 100644
|
||||
--- a/src/header/fcntl/linux.rs
|
||||
+++ b/src/header/fcntl/linux.rs
|
||||
@@ -15,7 +15,7 @@ pub const O_DIRECTORY: c_int = 0x1_0000;
|
||||
pub const O_NOFOLLOW: c_int = 0x2_0000;
|
||||
pub const O_CLOEXEC: c_int = 0x8_0000;
|
||||
pub const O_PATH: c_int = 0x20_0000;
|
||||
|
||||
-pub const FD_CLOEXEC: c_int = 0x8_0000;
|
||||
+pub const FD_CLOEXEC: c_int = 1;
|
||||
|
||||
// Defined for compatibility
|
||||
pub const O_NDELAY: c_int = O_NONBLOCK;
|
||||
diff --git a/src/header/mod.rs b/src/header/mod.rs
|
||||
index d3a7ba75..72f82084 100644
|
||||
index d3a7ba75..4cdc9f1d 100644
|
||||
--- a/src/header/mod.rs
|
||||
+++ b/src/header/mod.rs
|
||||
@@ -89,20 +89,23 @@ pub mod strings;
|
||||
// TODO: stropts.h (deprecated)
|
||||
pub mod sys_auxv;
|
||||
pub mod sys_epoll;
|
||||
+pub mod sys_eventfd;
|
||||
pub mod sys_file;
|
||||
pub mod sys_ioctl;
|
||||
-// TODO: sys/ipc.h
|
||||
+pub mod sys_ipc;
|
||||
pub mod sys_mman;
|
||||
// TODO: sys/msg.h
|
||||
pub mod sys_ptrace;
|
||||
pub mod sys_resource;
|
||||
pub mod sys_select;
|
||||
-// TODO: sys/sem.h
|
||||
-// TODO: sys/shm.h
|
||||
+pub mod sys_sem;
|
||||
+pub mod sys_shm;
|
||||
pub mod sys_socket;
|
||||
pub mod sys_stat;
|
||||
pub mod sys_statvfs;
|
||||
pub mod sys_time;
|
||||
+pub mod sys_timerfd;
|
||||
+pub mod sys_signalfd;
|
||||
#[deprecated]
|
||||
pub mod sys_timeb;
|
||||
//pub mod sys_times;
|
||||
diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs
|
||||
index 858d5ed4..5b5172aa 100644
|
||||
--- a/src/header/signal/mod.rs
|
||||
+++ b/src/header/signal/mod.rs
|
||||
@@ -32,6 +32,9 @@ pub mod sys;
|
||||
#[path = "redox.rs"]
|
||||
pub mod sys;
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
+mod signalfd;
|
||||
+pub use self::signalfd::*;
|
||||
pub mod _aio;
|
||||
pub mod _fenv;
|
||||
+pub mod arpa_nameser;
|
||||
pub mod arpa_inet;
|
||||
pub mod assert;
|
||||
pub mod bits_arpainet;
|
||||
@@ -66,6 +67,7 @@ pub mod pty;
|
||||
pub mod pwd;
|
||||
// TODO: re_comp.h (deprecated)
|
||||
pub mod regex;
|
||||
+pub mod resolv;
|
||||
// TODO: regexp.h (deprecated)
|
||||
pub mod sched;
|
||||
// TODO: search.h
|
||||
diff --git a/src/header/arpa_nameser/cbindgen.toml b/src/header/arpa_nameser/cbindgen.toml
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/src/header/arpa_nameser/cbindgen.toml
|
||||
@@ -0,0 +1,9 @@
|
||||
+sys_includes = ["sys/types.h", "stdint.h"]
|
||||
+include_guard = "_ARPA_NAMESER_H"
|
||||
+trailer = """
|
||||
+typedef struct HEADER HEADER;
|
||||
+"""
|
||||
+language = "C"
|
||||
+style = "Tag"
|
||||
+no_includes = true
|
||||
+cpp_compat = true
|
||||
diff --git a/src/header/arpa_nameser/mod.rs b/src/header/arpa_nameser/mod.rs
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/src/header/arpa_nameser/mod.rs
|
||||
@@ -0,0 +1,74 @@
|
||||
+//! `arpa/nameser.h` compatibility surface.
|
||||
+
|
||||
type SigSet = BitSet<[u64; 1]>;
|
||||
|
||||
pub(crate) const SIG_DFL: usize = 0;
|
||||
diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs
|
||||
index 069d4556..f7fe791a 100644
|
||||
--- a/src/header/stdio/mod.rs
|
||||
+++ b/src/header/stdio/mod.rs
|
||||
@@ -47,6 +47,9 @@ mod default;
|
||||
pub use self::getdelim::*;
|
||||
mod getdelim;
|
||||
|
||||
+pub use self::open_memstream::*;
|
||||
+mod open_memstream;
|
||||
+use crate::{
|
||||
+ header::errno::EINVAL,
|
||||
+ platform::{
|
||||
+ ERRNO,
|
||||
+ types::{c_char, c_int, c_uchar},
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
mod ext;
|
||||
mod helpers;
|
||||
pub mod printf;
|
||||
diff --git a/src/header/stdlib/cbindgen.toml b/src/header/stdlib/cbindgen.toml
|
||||
index 2e02e68a..07867c32 100644
|
||||
--- a/src/header/stdlib/cbindgen.toml
|
||||
+++ b/src/header/stdlib/cbindgen.toml
|
||||
@@ -1,7 +1,20 @@
|
||||
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
|
||||
+pub const HFIXEDSZ: c_int = 12;
|
||||
+pub const MAXDNAME: c_int = 256;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern \"C\" {
|
||||
+#endif
|
||||
+
|
||||
long double strtold(const char *nptr, char **endptr);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+#[repr(C)]
|
||||
+#[derive(Clone, Copy, Default)]
|
||||
+#[allow(non_camel_case_types)]
|
||||
+pub struct HEADER {
|
||||
+ pub id: u16,
|
||||
+ pub flags: u16,
|
||||
+ pub qdcount: u16,
|
||||
+ pub ancount: u16,
|
||||
+ pub nscount: u16,
|
||||
+ pub arcount: u16,
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
"""
|
||||
language = "C"
|
||||
style = "Type"
|
||||
diff --git a/src/header/sys_socket/constants.rs b/src/header/sys_socket/constants.rs
|
||||
index ec42889b..bebfc7b2 100644
|
||||
--- a/src/header/sys_socket/constants.rs
|
||||
+++ b/src/header/sys_socket/constants.rs
|
||||
@@ -51,6 +51,7 @@ pub const MSG_TRUNC: c_int = 32;
|
||||
pub const MSG_DONTWAIT: c_int = 64;
|
||||
pub const MSG_WAITALL: c_int = 256;
|
||||
pub const MSG_CMSG_CLOEXEC: c_int = 0x40000000;
|
||||
+pub const MSG_NOSIGNAL: c_int = 0x4000;
|
||||
|
||||
pub const IP_ADD_SOURCE_MEMBERSHIP: c_int = 70;
|
||||
pub const IP_DROP_SOURCE_MEMBERSHIP: c_int = 71;
|
||||
diff --git a/src/header/sys_socket/mod.rs b/src/header/sys_socket/mod.rs
|
||||
index 1c0c6d74..73a7f2e7 100644
|
||||
--- a/src/header/sys_socket/mod.rs
|
||||
+++ b/src/header/sys_socket/mod.rs
|
||||
@@ -334,6 +334,7 @@ pub unsafe extern "C" fn recvfrom(
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/recvmsg.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t {
|
||||
+ let flags = flags & !constants::MSG_NOSIGNAL;
|
||||
unsafe { Sys::recvmsg(socket, msg, flags) }
|
||||
.map(|r| r as ssize_t)
|
||||
.or_minus_one_errno()
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub extern "C" fn _cbindgen_export_nameser_header(header: HEADER) {
|
||||
+ let _ = header;
|
||||
+}
|
||||
+
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub unsafe extern "C" fn dn_expand(
|
||||
+ msg: *const c_uchar,
|
||||
+ eomorig: *const c_uchar,
|
||||
+ comp_dn: *const c_uchar,
|
||||
+ exp_dn: *mut c_char,
|
||||
+ length: c_int,
|
||||
+) -> c_int {
|
||||
+ if msg.is_null() || eomorig.is_null() || comp_dn.is_null() || exp_dn.is_null() || length <= 0 {
|
||||
+ ERRNO.set(EINVAL);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ let mut src = comp_dn;
|
||||
+ let mut out = exp_dn.cast::<u8>();
|
||||
+ let end = unsafe { exp_dn.add(length as usize) }.cast::<u8>();
|
||||
+ let mut consumed: isize = 0;
|
||||
+ let mut first = true;
|
||||
+
|
||||
+ loop {
|
||||
+ if src >= eomorig {
|
||||
+ ERRNO.set(EINVAL);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ let len = unsafe { *src };
|
||||
+ src = unsafe { src.add(1) };
|
||||
+ consumed += 1;
|
||||
+ if len == 0 {
|
||||
+ if out >= end { ERRNO.set(EINVAL); return -1; }
|
||||
+ unsafe { *out = 0 };
|
||||
+ return consumed as c_int;
|
||||
+ }
|
||||
+ if len & 0xC0 != 0 { ERRNO.set(EINVAL); return -1; }
|
||||
+ if !first {
|
||||
+ if out >= end { ERRNO.set(EINVAL); return -1; }
|
||||
+ unsafe { *out = b'.' };
|
||||
+ out = unsafe { out.add(1) };
|
||||
+ }
|
||||
+ first = false;
|
||||
+ if unsafe { src.add(len as usize) } > eomorig || unsafe { out.add(len as usize) } >= end { ERRNO.set(EINVAL); return -1; }
|
||||
+ unsafe { core::ptr::copy_nonoverlapping(src, out, len as usize); out = out.add(len as usize); src = src.add(len as usize); }
|
||||
+ consumed += len as isize;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/header/resolv/cbindgen.toml b/src/header/resolv/cbindgen.toml
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/src/header/resolv/cbindgen.toml
|
||||
@@ -0,0 +1,6 @@
|
||||
+sys_includes = ["sys/types.h", "netdb.h"]
|
||||
+include_guard = "_RESOLV_H"
|
||||
+language = "C"
|
||||
+style = "Tag"
|
||||
+no_includes = true
|
||||
+cpp_compat = true
|
||||
diff --git a/src/header/resolv/mod.rs b/src/header/resolv/mod.rs
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/src/header/resolv/mod.rs
|
||||
@@ -0,0 +1,54 @@
|
||||
+//! `resolv.h` bounded compatibility surface.
|
||||
+
|
||||
+use crate::{
|
||||
+ header::{arpa_nameser::dn_expand, errno::ENOSYS, netdb},
|
||||
+ platform::{
|
||||
+ ERRNO,
|
||||
+ types::{c_char, c_int, c_uchar},
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+pub const RES_INIT: c_int = 0x0000_0001;
|
||||
+pub const RES_DEBUG: c_int = 0x0000_0002;
|
||||
+pub const RES_USE_EDNS0: c_int = 0x0008_0000;
|
||||
+pub const RES_USE_DNSSEC: c_int = 0x0010_0000;
|
||||
+
|
||||
+#[repr(C)]
|
||||
+#[derive(Clone, Copy, Default)]
|
||||
+#[allow(non_camel_case_types)]
|
||||
+pub struct __res_state {
|
||||
+ pub options: c_int,
|
||||
+}
|
||||
+
|
||||
+pub type res_state = *mut __res_state;
|
||||
+
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub static mut _res: __res_state = __res_state { options: 0 };
|
||||
+
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub extern "C" fn _cbindgen_export_res_state(state: __res_state) {
|
||||
+ let _ = state;
|
||||
+}
|
||||
+
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub unsafe extern "C" fn res_init() -> c_int {
|
||||
+ unsafe { _res.options |= RES_INIT; }
|
||||
+ 0
|
||||
+}
|
||||
+
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub unsafe extern "C" fn res_query(_dname: *const c_char, _class: c_int, _rtype: c_int, _answer: *mut c_uchar, _anslen: c_int) -> c_int {
|
||||
+ netdb::H_ERRNO.set(netdb::NO_DATA);
|
||||
+ ERRNO.set(ENOSYS);
|
||||
+ -1
|
||||
+}
|
||||
+
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub unsafe extern "C" fn res_search(dname: *const c_char, class: c_int, rtype: c_int, answer: *mut c_uchar, anslen: c_int) -> c_int {
|
||||
+ unsafe { res_query(dname, class, rtype, answer, anslen) }
|
||||
+}
|
||||
+
|
||||
+#[unsafe(no_mangle)]
|
||||
+pub unsafe extern "C" fn __dn_expand(msg: *const c_uchar, eomorig: *const c_uchar, comp_dn: *const c_uchar, exp_dn: *mut c_char, length: c_int) -> c_int {
|
||||
+ unsafe { dn_expand(msg, eomorig, comp_dn, exp_dn, length) }
|
||||
+}
|
||||
|
||||
Reference in New Issue
Block a user