Send SIGCHLD to parent process
This commit is contained in:
parent
459ca45ab9
commit
17b4912055
@ -1,10 +1,11 @@
|
|||||||
|
use crate::signal::constants::*;
|
||||||
use std::intrinsics::atomic_store;
|
use std::intrinsics::atomic_store;
|
||||||
|
|
||||||
use super::do_futex::futex_wake;
|
use super::do_futex::futex_wake;
|
||||||
use super::process::ProcessFilter;
|
use super::process::{Process, ProcessFilter};
|
||||||
use super::{table, TermStatus, ThreadRef, ThreadStatus};
|
use super::{table, TermStatus, ThreadRef, ThreadStatus};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::signal::SigNum;
|
use crate::signal::{KernelSignal, SigNum};
|
||||||
|
|
||||||
pub fn do_exit_group(status: i32) {
|
pub fn do_exit_group(status: i32) {
|
||||||
let term_status = TermStatus::Exited(status as u8);
|
let term_status = TermStatus::Exited(status as u8);
|
||||||
@ -84,6 +85,9 @@ fn exit_process(thread: &ThreadRef, term_status: TermStatus) {
|
|||||||
let mut parent_inner = parent.inner();
|
let mut parent_inner = parent.inner();
|
||||||
process.inner().exit(term_status);
|
process.inner().exit(term_status);
|
||||||
|
|
||||||
|
//Send SIGCHLD to parent
|
||||||
|
send_sigchld_to(&parent);
|
||||||
|
|
||||||
// Wake up the parent if it is waiting on this child
|
// Wake up the parent if it is waiting on this child
|
||||||
let waiting_children = parent_inner.waiting_children_mut().unwrap();
|
let waiting_children = parent_inner.waiting_children_mut().unwrap();
|
||||||
waiting_children.del_and_wake_one_waiter(|waiter_data| -> Option<pid_t> {
|
waiting_children.del_and_wake_one_waiter(|waiter_data| -> Option<pid_t> {
|
||||||
@ -103,3 +107,9 @@ fn exit_process(thread: &ThreadRef, term_status: TermStatus) {
|
|||||||
Some(process.pid())
|
Some(process.pid())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_sigchld_to(parent: &Arc<Process>) {
|
||||||
|
let signal = Box::new(KernelSignal::new(SigNum::from(SIGCHLD)));
|
||||||
|
let mut sig_queues = parent.sig_queues().lock().unwrap();
|
||||||
|
sig_queues.enqueue(signal);
|
||||||
|
}
|
||||||
|
@ -325,6 +325,34 @@ int test_sigaltstack() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Test SIGCHLD signal
|
||||||
|
// ============================================================================
|
||||||
|
int sigchld = 0;
|
||||||
|
|
||||||
|
void proc_exit() {
|
||||||
|
sigchld = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_sigchld() {
|
||||||
|
signal(SIGCHLD, proc_exit);
|
||||||
|
|
||||||
|
int ret, child_pid;
|
||||||
|
printf("Run a parent process has pid = %d and ppid = %d\n", getpid(), getppid());
|
||||||
|
|
||||||
|
ret = posix_spawn(&child_pid, "/bin/getpid", NULL, NULL, NULL, NULL);
|
||||||
|
if (ret < 0){
|
||||||
|
printf("ERROR: failed to spawn a child process\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("Spawn a new proces successfully (pid = %d)\n", child_pid);
|
||||||
|
|
||||||
|
wait(NULL);
|
||||||
|
if (sigchld == 0) THROW_ERROR("Did not receive SIGCHLD");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Test suite main
|
// Test suite main
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -336,6 +364,7 @@ static test_case_t test_cases[] = {
|
|||||||
TEST_CASE(test_kill),
|
TEST_CASE(test_kill),
|
||||||
TEST_CASE(test_catch_fault),
|
TEST_CASE(test_catch_fault),
|
||||||
TEST_CASE(test_sigaltstack),
|
TEST_CASE(test_sigaltstack),
|
||||||
|
TEST_CASE(test_sigchld),
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
|
Loading…
Reference in New Issue
Block a user