absorb: 27 orphaned relibc patches re-applied (Phase 1.0A)

Per local/docs/PATCH-PRESERVATION-AUDIT-2026-07-12.md the relibc
fork was carrying only 34 of 90 patches in local/patches/relibc/.
The other 56 patches' content was silently missing from the fork.

This commit re-applies 27 patches that genuinely still apply
cleanly. Recovery covers:

- eventfd implementation (sys/eventfd.h + eventfd.rs)
- signalfd implementation (sys/signalfd.h + signalfd.rs)
- timerfd implementation (sys/timerfd.h + timerfd.rs)
- bits/eventfd.h header
- spawn() function: cbindgen + stdint fix
- P3-timerfd-cbindgen-fix
- cbindgen language=C fixes for sys/{timerfd,semaphore}
- stdint include chain fixes
- strtold implementation
- dns aaaa getaddrinfo ipv6
- various stack/threading/header threading fixes
- dup3 syscalls
- waitid implementation
- bits/timespec reverse_from
- open_memstream integration

24 files changed.
This commit is contained in:
Red Bear OS
2026-07-12 01:29:50 +03:00
parent d60ba8730d
commit fa54b985ff
25 changed files with 931 additions and 125 deletions
+3
View File
@@ -49,6 +49,9 @@ mod default;
pub use self::getdelim::*;
mod getdelim;
pub use self::open_memstream::*;
mod open_memstream;
mod ext;
mod helpers;
pub mod printf;
+124
View File
@@ -0,0 +1,124 @@
use alloc::{boxed::Box, vec, vec::Vec};
use core::ptr;
use super::{
Buffer, FILE,
constants::{BUFSIZ, F_NORD},
};
use crate::{
error::{Errno, ResultExtPtrMut},
fs::File,
header::{
errno::{EFAULT, ENOMEM},
fcntl, pthread, stdlib, unistd,
},
io::{self, BufWriter, Write},
platform::{
ERRNO,
types::{c_char, size_t},
},
};
struct MemstreamWriter {
bufp: *mut *mut c_char,
sizep: *mut size_t,
current: *mut c_char,
buffer: Vec<u8>,
}
unsafe impl Send for MemstreamWriter {}
impl MemstreamWriter {
fn new(bufp: *mut *mut c_char, sizep: *mut size_t) -> Self {
Self {
bufp,
sizep,
current: ptr::null_mut(),
buffer: Vec::new(),
}
}
fn sync_output(&mut self) -> io::Result<()> {
let size = self.buffer.len();
let alloc_size = size
.checked_add(1)
.ok_or_else(|| io::Error::from_raw_os_error(ENOMEM))?;
let raw = if self.current.is_null() {
unsafe { stdlib::malloc(alloc_size) }
} else {
unsafe { stdlib::realloc(self.current.cast(), alloc_size) }
};
if raw.is_null() {
return Err(io::Error::from_raw_os_error(ENOMEM));
}
let raw = raw.cast::<c_char>();
if size != 0 {
unsafe { ptr::copy_nonoverlapping(self.buffer.as_ptr(), raw.cast::<u8>(), size) };
}
unsafe {
*raw.add(size) = 0;
*self.bufp = raw;
*self.sizep = size;
}
self.current = raw;
Ok(())
}
}
impl Write for MemstreamWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.buffer
.try_reserve(buf.len())
.map_err(|_| io::Error::from_raw_os_error(ENOMEM))?;
self.buffer.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
self.sync_output()
}
}
fn create_memstream(bufp: *mut *mut c_char, sizep: *mut size_t) -> Result<Box<FILE>, Errno> {
if bufp.is_null() || sizep.is_null() {
return Err(Errno(EFAULT));
}
unsafe {
*bufp = ptr::null_mut();
*sizep = 0;
}
let mut fds = [0; 2];
if unsafe { unistd::pipe2(fds.as_mut_ptr(), fcntl::O_CLOEXEC) } != 0 {
return Err(Errno(ERRNO.get()));
}
let _ = unistd::close(fds[0]);
let file = File::new(fds[1]);
let writer = Box::new(BufWriter::new(MemstreamWriter::new(bufp, sizep)));
let mutex_attr = pthread::RlctMutexAttr {
ty: pthread::PTHREAD_MUTEX_RECURSIVE,
..Default::default()
};
Ok(Box::new(FILE {
lock: pthread::RlctMutex::new(&mutex_attr).unwrap(),
file,
flags: F_NORD,
read_buf: Buffer::Owned(vec![0; BUFSIZ as usize]),
read_pos: 0,
read_size: 0,
unget: Vec::new(),
writer,
pid: None,
orientation: 0,
}))
}
#[unsafe(no_mangle)]
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()
}