Respect user-defined exit signal in clone() and clone3()

When calling clone() and clone3(), the user is allowed to specify a
signal to be sent to the parent process on exit. Respect this value by
storing it in the Process struct and sending the signal on exit.

Add a test as well to verify that the signal is properly delivered to
the parent.
This commit is contained in:
Carlos López
2024-09-24 21:33:10 +02:00
committed by Tate, Hongliang Tian
parent 130a0f7030
commit 0a36760f7a
7 changed files with 122 additions and 14 deletions

View File

@ -345,6 +345,10 @@ fn clone_child_process(
process_builder.build()?
};
if let Some(sig) = clone_args.exit_signal {
child.set_exit_signal(sig);
};
// Deals with clone flags
let child_thread = thread_table::get_thread(child_tid).unwrap();
let child_posix_thread = child_thread.as_posix_thread().unwrap();

View File

@ -5,7 +5,7 @@ use crate::{
prelude::*,
process::{
posix_thread::{do_exit, PosixThreadExt},
signal::{constants::SIGCHLD, signals::kernel::KernelSignal},
signal::signals::kernel::KernelSignal,
},
thread::Thread,
};
@ -60,10 +60,11 @@ pub fn do_exit_group(term_status: TermStatus) {
let parent = current.parent().lock().process();
if let Some(parent) = parent.upgrade() {
// Notify parent
let signal = KernelSignal::new(SIGCHLD);
parent.enqueue_signal(signal);
if let Some(signal) = current.exit_signal().map(KernelSignal::new) {
parent.enqueue_signal(signal);
};
parent.children_wait_queue().wake_all();
}
};
}
const INIT_PROCESS_PID: Pid = 1;

View File

@ -101,6 +101,9 @@ pub struct Process {
/// The signal that the process should receive when parent process exits.
parent_death_signal: AtomicSigNum,
/// The signal that should be sent to the parent when this process exits.
exit_signal: AtomicSigNum,
/// A profiling clock measures the user CPU time and kernel CPU time of the current process.
prof_clock: Arc<ProfClock>,
@ -218,6 +221,7 @@ impl Process {
umask,
sig_dispositions,
parent_death_signal: AtomicSigNum::new_empty(),
exit_signal: AtomicSigNum::new_empty(),
resource_limits: Mutex::new(resource_limits),
nice: Atomic::new(nice),
timer_manager: PosixTimerManager::new(&prof_clock, process_ref),
@ -690,6 +694,14 @@ impl Process {
self.parent_death_signal.as_sig_num()
}
pub fn set_exit_signal(&self, sig_num: SigNum) {
self.exit_signal.set(sig_num);
}
pub fn exit_signal(&self) -> Option<SigNum> {
self.exit_signal.as_sig_num()
}
// ******************* Status ********************
fn set_runnable(&self) {