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 super::do_futex::futex_wake;
 | 
			
		||||
use super::process::ProcessFilter;
 | 
			
		||||
use super::process::{Process, ProcessFilter};
 | 
			
		||||
use super::{table, TermStatus, ThreadRef, ThreadStatus};
 | 
			
		||||
use crate::prelude::*;
 | 
			
		||||
use crate::signal::SigNum;
 | 
			
		||||
use crate::signal::{KernelSignal, SigNum};
 | 
			
		||||
 | 
			
		||||
pub fn do_exit_group(status: i32) {
 | 
			
		||||
    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();
 | 
			
		||||
    process.inner().exit(term_status);
 | 
			
		||||
 | 
			
		||||
    //Send SIGCHLD to parent
 | 
			
		||||
    send_sigchld_to(&parent);
 | 
			
		||||
 | 
			
		||||
    // Wake up the parent if it is waiting on this child
 | 
			
		||||
    let waiting_children = parent_inner.waiting_children_mut().unwrap();
 | 
			
		||||
    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())
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
// 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
 | 
			
		||||
// ============================================================================
 | 
			
		||||
@ -336,6 +364,7 @@ static test_case_t test_cases[] = {
 | 
			
		||||
    TEST_CASE(test_kill),
 | 
			
		||||
    TEST_CASE(test_catch_fault),
 | 
			
		||||
    TEST_CASE(test_sigaltstack),
 | 
			
		||||
    TEST_CASE(test_sigchld),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int argc, const char* argv[]) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user