diff --git a/local/patches/relibc/P3-ifaddrs-net_if.patch b/local/patches/relibc/P3-ifaddrs-net_if.patch new file mode 100644 index 00000000..378412d5 --- /dev/null +++ b/local/patches/relibc/P3-ifaddrs-net_if.patch @@ -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 . + + 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::() } else { 0 }; ++ let netmask_size = if entry.netmask.is_some() { core::mem::size_of::() } else { 0 }; ++ let total = core::mem::size_of::() + name_len + addr_size + netmask_size; ++ let 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::(); ++ let mut cursor = unsafe { raw.add(core::mem::size_of::()) }; ++ ++ let name_ptr = cursor.cast::(); ++ 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::(); ++ unsafe { ptr.write(ipv4_addr(addr)) }; ++ cursor = unsafe { cursor.add(core::mem::size_of::()) }; ++ ptr.cast::() ++ } else { ++ core::ptr::null_mut() ++ }; ++ ++ let netmask_ptr = if let Some(netmask) = entry.netmask { ++ let ptr = cursor.cast::(); ++ unsafe { ptr.write(ipv4_addr(netmask)) }; ++ ptr.cast::() ++ } 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 . + 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::(), +- }, +-]; ++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::(), ++ }, ++ ] ++} + + /// See . + /// +@@ -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::() +@@ -66,7 +112,17 @@ pub unsafe extern "C" fn if_indextoname(idx: c_uint, buf: *mut c_char) -> *const + /// The end of the list is determined by an if_nameindex struct having if_index 0 and if_name NULL + #[unsafe(no_mangle)] + pub unsafe extern "C" fn if_nameindex() -> *const if_nameindex { +- core::ptr::from_ref::(&INTERFACES[0]) ++ static mut TABLE: [if_nameindex; 3] = [ ++ if_nameindex { if_index: 0, if_name: core::ptr::null() }, ++ if_nameindex { if_index: 0, if_name: core::ptr::null() }, ++ if_nameindex { if_index: 0, if_name: core::ptr::null() }, ++ ]; ++ ++ let computed = interface_nameindex_table(); ++ unsafe { ++ TABLE = computed; ++ core::ptr::from_ref::(&TABLE[0]) ++ } + } + + /// See . +@@ -80,8 +136,11 @@ pub unsafe extern "C" fn if_nametoindex(name: *const c_char) -> c_uint { + 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 + } diff --git a/local/patches/relibc/P3-signalfd-header.patch b/local/patches/relibc/P3-signalfd-header.patch index e4fd0441..a97a84b1 100644 --- a/local/patches/relibc/P3-signalfd-header.patch +++ b/local/patches/relibc/P3-signalfd-header.patch @@ -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 diff --git a/local/patches/relibc/P3-timerfd.patch b/local/patches/relibc/P3-timerfd.patch index 62e5c510..bd5061de 100644 --- a/local/patches/relibc/P3-timerfd.patch +++ b/local/patches/relibc/P3-timerfd.patch @@ -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 diff --git a/local/patches/relibc/P3-waitid.patch b/local/patches/relibc/P3-waitid.patch index 489cfead..4675a81e 100644 --- a/local/patches/relibc/P3-waitid.patch +++ b/local/patches/relibc/P3-waitid.patch @@ -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 . +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 . #[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 . +fn map_waitid_target(idtype: idtype_t, id: id_t) -> Option { + match idtype { + P_ALL => Some(-1), @@ -75,6 +73,25 @@ index 11f4bf2c..91a58c5b 100644 + } +} + ++fn map_waitid_options(options: c_int) -> Option { ++ 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 . #[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() diff --git a/local/patches/relibc/redox.patch b/local/patches/relibc/redox.patch index f425201e..a58b32b8 100644 --- a/local/patches/relibc/redox.patch +++ b/local/patches/relibc/redox.patch @@ -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 . - #[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::(); ++ let end = unsafe { exp_dn.add(length as usize) }.cast::(); ++ 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) } ++} diff --git a/recipes/core/relibc/recipe.toml b/recipes/core/relibc/recipe.toml index af2e2ab7..18f683a4 100644 --- a/recipes/core/relibc/recipe.toml +++ b/recipes/core/relibc/recipe.toml @@ -1,6 +1,21 @@ [source] git = "https://gitlab.redox-os.org/redox-os/relibc.git" -patches = ["redox.patch"] +patches = [ + "../../../local/patches/relibc/redox.patch", + "../../../local/patches/relibc/P3-eventfd.patch", + "../../../local/patches/relibc/P3-signalfd.patch", + "../../../local/patches/relibc/P3-signalfd-header.patch", + "../../../local/patches/relibc/P3-timerfd.patch", + "../../../local/patches/relibc/P3-open-memstream.patch", + "../../../local/patches/relibc/P3-socket-flags.patch", + "../../../local/patches/relibc/P3-ifaddrs-net_if.patch", + "../../../local/patches/relibc/P3-waitid.patch", + "../../../local/patches/relibc/P3-waitid-header.patch", + "../../../local/patches/relibc/P3-sysv-ipc.patch", + "../../../local/patches/relibc/P3-sysv-sem-impl.patch", + "../../../local/patches/relibc/P3-sysv-shm-impl.patch", + "../../../local/patches/relibc/P3-ipc-tests.patch", +] [build] template = "custom"