ast_comparator/test/student_data/handout/shlab-handout/cases/reference_9_tsh.c
/////////////////////////////////////////////////////////////////////////////
//
// sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
//     a child job terminates (becomes a zombie), or stops because it
//     received a SIGSTOP or SIGTSTP signal. The handler reaps all
//     available zombie children, but doesn't wait for any other
//     currently running children to terminate.  
//
The kernel sends a SIGCHLD to the shell whenever
a child job terminates (becomes a zombie), or stops because it
received a SIGSTOP or SIGTSTP signal. The handler reaps all
available zombie children, but doesn't wait for any other
currently running children to terminate.
The kernel sends a SIGCHLD to the shell whenever a child job terminates ( becomes a zombie ) or stops because it received a SIGSTOP or SIGTSTP signal . The handler reaps all available zombie children but doesn ' t wait for any other currently running children to terminate .
void sigchld_handler(int sig) 
{
    int status; 
    pid_t pid;  
    while((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0){
        if(WIFSTOPPED(status)){ 
            struct job_t *job = getjobpid(jobs, pid); 
            job->state = ST;
            printf("Job [%d] (%d) stopped by signal 20\n", job->jid, pid);
            return;
        }
        else if(WIFSIGNALED(status)){ 
            struct job_t *job = getjobpid(jobs, pid); 
            printf("Job [%d] (%d) terminated by signal 2\n", job->jid, pid);
            deletejob(jobs, pid);
        }
        else{       
            deletejob(jobs, pid);
            }
        }       
    return; 
}
void sigchld_handler ( int sig ) { int status ; pid_t pid ; while ( ( pid = waitpid ( -1 , & status , WNOHANG | WUNTRACED ) ) > 0 ) { if ( WIFSTOPPED ( status ) ) { struct job_t * job = getjobpid ( jobs , pid ) ; job -> state = ST ; printf ( " \n " , job -> jid , pid ) ; return ; } else if ( WIFSIGNALED ( status ) ) { struct job_t * job = getjobpid ( jobs , pid ) ; printf ( " \n " , job -> jid , pid ) ; deletejob ( jobs , pid ) ; } else { deletejob ( jobs , pid ) ; } } return ; }
sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
a child job terminates (becomes a zombie), or stops because it
received a SIGSTOP or SIGTSTP signal.
sigchld_handler - The kernel sends a SIGCHLD to the shell whenever a child job terminates ( becomes a zombie ) or stops because it received a SIGSTOP or SIGTSTP signal .
//signal tells us there is a child and we need to wait until that child is done executing, so use waitpid function //location where waitpid can store a status value, if value is zero child process returns zero, otherwise it can be analyzed //specifies the child processes the caller wants to wait for //if pid is -1, waitpid() waits for any child process to end, so this will let any child processes end before reaping them //WNOHANG checks child processes without causing the caller to be suspended //when using WHNOHANG and there is at least one process (usually a child) whose status information is not available, waitpid returns 0 // because if this we need our waitpid function to return a value greater than zero before we delete/reap that child. // http://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rtwaip.htm for refresher //WUNTRACED is for non terminated processes (stopped processes) //if the process is stopped, do nothing except change the state to stopped. WIFSTOPPED returns true if child is currently stopped //used for print statement //catches ctrl-c, the interupt signal which has a default action of terminate //used for print statement