Files
RedBear-OS/local/patches/relibc/redox.patch
T
vasilito 2d22c6ad59 chore: commit durable overlay state (configs, patches, recipe symlinks)
Pre-existing work from other sessions committed as durable state:
- local/config/drivers.d/ (8 driver configs)
- local/config/firmware-fallbacks.d/ (3 firmware configs)
- local/patches/base/, kernel/, relibc/ (new patch carriers)
- recipes/system/ symlinks (driver-params, acmd, ecmd, usbaudiod)

pkgar build artifacts and cache intentionally excluded.
2026-05-01 03:11:21 +01:00

128 lines
4.0 KiB
Diff

diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs
--- a/src/header/fcntl/mod.rs
+++ b/src/header/fcntl/mod.rs
@@ -9,0 +10 @@
+ header::unistd::close,
@@ -75,0 +77,17 @@
+
+ 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;
+ }
diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs
--- a/src/pthread/mod.rs
+++ b/src/pthread/mod.rs
@@ -2,6 +2,7 @@
use core::{
cell::UnsafeCell,
+ panic::AssertUnwindSafe,
ptr,
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
};
@@ -208,13 +209,41 @@ pub(crate) unsafe fn create(
}
/// A shim to wrap thread entry points in logic to set up TLS, for example
+fn catch_unwind<F: FnOnce()>(f: AssertUnwindSafe<F>) -> Result<(), ()> {
+ fn do_call<F: FnOnce()>(data: *mut u8) {
+ let callback = unsafe { &mut *data.cast::<Option<AssertUnwindSafe<F>>>() };
+ if let Some(callback) = callback.take() {
+ callback.0();
+ }
+ }
+
+ fn do_catch<F: FnOnce()>(_data: *mut u8, _payload: *mut u8) {}
+
+ let mut callback = Some(f);
+ let panicked = unsafe {
+ core::intrinsics::catch_unwind(
+ do_call::<F>,
+ (&mut callback as *mut Option<AssertUnwindSafe<F>>).cast(),
+ do_catch::<F>,
+ ) != 0
+ };
+
+ if panicked { Err(()) } else { Ok(()) }
+}
+
unsafe extern "C" fn new_thread_shim(
tcb: *mut Tcb,
synchronization_mutex: *const Mutex<u64>,
) -> ! {
- let tcb = unsafe { tcb.as_mut() }.expect_notls("non-null TLS is required");
+ let tcb = match unsafe { tcb.as_mut() } {
+ Some(tcb) => tcb,
+ None => {
+ log::error!("pthread: child thread started without a TCB");
+ unsafe { exit_current_thread(Retval(ptr::null_mut())) }
+ }
+ };
#[cfg(not(target_os = "redox"))]
{
@@ -227,12 +256,23 @@ unsafe extern "C" fn new_thread_shim(
unsafe {
tcb.activate(None);
}
- redox_rt::signal::setup_sighandler(&tcb.os_specific, false);
+ match catch_unwind(AssertUnwindSafe(|| {
+ redox_rt::signal::setup_sighandler(&tcb.os_specific, false)
+ })) {
+ Ok(()) => {}
+ Err(()) => {
+ log::error!("pthread: failed to set up child thread signal handler");
+ unsafe { exit_current_thread(Retval(ptr::null_mut())) }
+ }
+ }
}
let procmask = unsafe { (&*synchronization_mutex).as_ptr().read() };
- unsafe { tcb.copy_masters() }.unwrap();
+ if let Err(err) = unsafe { tcb.copy_masters() } {
+ log::error!("pthread: failed to copy TLS masters for child thread: {err:?}");
+ unsafe { exit_current_thread(Retval(ptr::null_mut())) }
+ }
unsafe { (*tcb).pthread.os_tid.get().write(Sys::current_os_tid()) };
@@ -240,11 +280,21 @@ unsafe extern "C" fn new_thread_shim(
#[cfg(target_os = "redox")]
{
- redox_rt::signal::set_sigmask(Some(procmask), None)
- .expect("failed to set procmask in child thread");
+ if let Err(err) = redox_rt::signal::set_sigmask(Some(procmask), None) {
+ log::error!("pthread: failed to set child thread signal mask: {err:?}");
+ }
}
- let retval = unsafe { entry_point(arg) };
+ let mut retval = ptr::null_mut();
+ match catch_unwind(AssertUnwindSafe(|| {
+ retval = unsafe { entry_point(arg) };
+ })) {
+ Ok(()) => {}
+ Err(()) => {
+ log::error!("pthread: child thread entry point panicked");
+ unsafe { exit_current_thread(Retval(ptr::null_mut())) }
+ }
+ }
unsafe { exit_current_thread(Retval(retval)) }
}