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:
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user