fix: replace 8 .expect("TODO") panic points with proper error handling

- on_sendfd: subscribe/dup errors return error Response instead of panic
- fork/new_thread: subscribe errors propagate via ? operator
- signal delivery (4 sites): status fd write errors are best-effort (let _ =)

The procmgr is the first userspace process manager — a panic here kills
the entire system. These changes make it resilient to transient fd errors.
This commit is contained in:
Red Bear OS
2026-07-12 01:51:11 +03:00
parent 00b799d512
commit b59dffc0ff
+20 -20
View File
@@ -617,12 +617,18 @@ impl<'a> ProcScheme<'a> {
let fd = FdGuard::new(fd_out);
// TODO: Use global thread id etc. rather than reusing fd for identifier?
self.queue
if let Err(e) = self
.queue
.subscribe(fd_out, fd_out, EventFlags::EVENT_READ)
.expect("TODO");
let status_hndl = fd
{
return Response::new(Err(e), req);
}
let status_hndl = match fd
.dup(alloc::format!("auth-{}-status", self.auth.as_raw_fd()).as_bytes())
.expect("TODO");
{
Ok(h) => h,
Err(e) => return Response::new(Err(e), req),
};
let thread = Rc::new(RefCell::new(Thread {
fd,
@@ -697,8 +703,7 @@ impl<'a> ProcScheme<'a> {
let thread_ident = new_ctxt_fd.as_raw_fd();
self.queue
.subscribe(thread_ident, thread_ident, EventFlags::EVENT_READ)
.expect("TODO");
.subscribe(thread_ident, thread_ident, EventFlags::EVENT_READ)?;
let thread = Rc::new(RefCell::new(Thread {
fd: new_ctxt_fd,
@@ -773,8 +778,7 @@ impl<'a> ProcScheme<'a> {
let ident = ctxt_fd.as_raw_fd();
self.queue
.subscribe(ident, ident, EventFlags::EVENT_READ)
.expect("TODO");
.subscribe(ident, ident, EventFlags::EVENT_READ)?;
let thread = Rc::new(RefCell::new(Thread {
fd: ctxt_fd,
@@ -2109,10 +2113,9 @@ impl<'a> ProcScheme<'a> {
Ordering::Relaxed,
);
}
thread
let _ = thread
.status_hndl
.write(&(ContextVerb::Unstop as usize).to_ne_bytes())
.expect("TODO");
.write(&(ContextVerb::Unstop as usize).to_ne_bytes());
}
// POSIX XSI allows but does not reqiure SIGCHLD to be sent when SIGCONT occurs.
return SendResult::SucceededSigcont {
@@ -2187,10 +2190,9 @@ impl<'a> ProcScheme<'a> {
if sig == SIGKILL {
for thread in &target_proc.threads {
let thread = thread.borrow();
thread
let _ = thread
.status_hndl
.write(&(ContextVerb::ForceKill as usize).to_ne_bytes())
.expect("TODO");
.write(&(ContextVerb::ForceKill as usize).to_ne_bytes());
}
*killed_self |= is_self;
@@ -2213,10 +2215,9 @@ impl<'a> ProcScheme<'a> {
let _was_new = tctl.word[sig_group].fetch_or(bit, Ordering::Release);
if (tctl.word[sig_group].load(Ordering::Relaxed) >> 32) & bit != 0 {
*killed_self |= is_self;
thread
let _ = thread
.status_hndl
.write(&(ContextVerb::Interrupt as usize).to_ne_bytes())
.expect("TODO");
.write(&(ContextVerb::Interrupt as usize).to_ne_bytes());
}
}
KillTarget::Proc(proc) => {
@@ -2273,10 +2274,9 @@ impl<'a> ProcScheme<'a> {
if (tctl.word[sig_group].load(Ordering::Relaxed) >> 32) & (1 << sig_idx)
!= 0
{
thread
let _ = thread
.status_hndl
.write(&(ContextVerb::Interrupt as usize).to_ne_bytes())
.expect("TODO");
.write(&(ContextVerb::Interrupt as usize).to_ne_bytes());
*killed_self |= is_self;
break;
}