mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 08:53:29 +00:00
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:
committed by
Tate, Hongliang Tian
parent
130a0f7030
commit
0a36760f7a
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -7,11 +7,7 @@ use ostd::cpu::UserContext;
|
||||
use super::SyscallReturn;
|
||||
use crate::{
|
||||
prelude::*,
|
||||
process::{
|
||||
clone_child,
|
||||
signal::{constants::SIGCHLD, sig_num::SigNum},
|
||||
CloneArgs, CloneFlags,
|
||||
},
|
||||
process::{clone_child, signal::sig_num::SigNum, CloneArgs, CloneFlags},
|
||||
};
|
||||
|
||||
// The order of arguments for clone differs in different architecture.
|
||||
@ -87,11 +83,7 @@ struct Clone3Args {
|
||||
|
||||
impl From<Clone3Args> for CloneArgs {
|
||||
fn from(value: Clone3Args) -> Self {
|
||||
// TODO: deal with pidfd, exit_signal, set_tid, set_tid_size, cgroup
|
||||
if value.exit_signal != 0 || value.exit_signal as u8 != SIGCHLD.as_u8() {
|
||||
warn!("exit signal is not supported");
|
||||
}
|
||||
|
||||
// TODO: deal with pidfd, set_tid, set_tid_size, cgroup
|
||||
if value.pidfd != 0 {
|
||||
warn!("pidfd is not supported");
|
||||
}
|
||||
|
Reference in New Issue
Block a user