ba360adfbc
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>
251 lines
7.1 KiB
Diff
251 lines
7.1 KiB
Diff
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/fcntl/mod.rs b/src/header/fcntl/mod.rs
|
|
index 6a4db2fa..82484375 100644
|
|
--- a/src/header/fcntl/mod.rs
|
|
+++ b/src/header/fcntl/mod.rs
|
|
@@ -7,6 +7,7 @@ use core::num::NonZeroU64;
|
|
use crate::{
|
|
c_str::CStr,
|
|
error::ResultExt,
|
|
+ header::unistd::close,
|
|
platform::{
|
|
Pal, Sys,
|
|
types::{c_char, c_int, c_short, c_ulonglong, mode_t, off_t, pid_t},
|
|
@@ -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 = 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 Sys::fcntl(new_fd, F_SETFD, FD_CLOEXEC as c_ulonglong).or_minus_one_errno() < 0 {
|
|
+ let _ = close(new_fd);
|
|
+ return -1;
|
|
+ }
|
|
+ return new_fd;
|
|
+ }
|
|
+
|
|
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..4cdc9f1d 100644
|
|
--- a/src/header/mod.rs
|
|
+++ b/src/header/mod.rs
|
|
@@ -2,6 +2,7 @@
|
|
|
|
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.
|
|
+
|
|
+use crate::{
|
|
+ header::errno::EINVAL,
|
|
+ platform::{
|
|
+ ERRNO,
|
|
+ types::{c_char, c_int, c_uchar},
|
|
+ },
|
|
+};
|
|
+
|
|
+pub const HFIXEDSZ: c_int = 12;
|
|
+pub const MAXDNAME: c_int = 256;
|
|
+
|
|
+#[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,
|
|
+}
|
|
+
|
|
+#[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) }
|
|
+}
|