ast_comparator/test/student_data/handout/shlab-handout/cases/reference_26_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;          
    struct job_t *pjob; 
    do {
        pid = waitpid(-1, &status, WNOHANG|WUNTRACED); 
        if (pid > 0) {
            if (WIFSTOPPED(status)) {
                if ((pjob = getjobpid(jobs, pid)) != NULL) {
                    pjob->state = ST; 
                    printf("Job [%d] (%d) stopped by signal 20\n", pjob->jid, pjob->pid);
                } else {
                    printf("sigchld_handler: getjobpid error\n");
                    exit(1);
                }
            } else if (WIFSIGNALED(status)) {
                if ((pjob = getjobpid(jobs, pid)) != NULL) {
                    printf("Job [%d] (%d) terminated by signal 2\n", pjob->jid, pjob->pid);
                    if (!deletejob(jobs, pid)) { 
                        printf("sigchld_handler: deletejob error\n");
                        exit(1);
                    }
                } else {
                    printf("sigchld_handler: getjobpid error\n");
                    exit(1);
                }
            } else if (WIFEXITED(status)) {
                if (!deletejob(jobs, pid)) {
                    printf("sigchld_handler: deletejob error\n");
                    exit(1);
                }
            } else {
                printf("Unknown waitpid\n");
                exit(1);
            }
        } else if (pid == -1 && errno == EINTR) {
            continue;
        } else {
            break;
        }
    } while (1);
    return;
}
void sigchld_handler ( int sig ) { int status ; pid_t pid ; struct job_t * pjob ; do { pid = waitpid ( -1 , & status , WNOHANG | WUNTRACED ) ; if ( pid > 0 ) { if ( WIFSTOPPED ( status ) ) { if ( ( pjob = getjobpid ( jobs , pid ) ) != NULL ) { pjob -> state = ST ; printf ( " \n " , pjob -> jid , pjob -> pid ) ; } else { printf ( " \n " ) ; exit ( 1 ) ; } } else if ( WIFSIGNALED ( status ) ) { if ( ( pjob = getjobpid ( jobs , pid ) ) != NULL ) { printf ( " \n " , pjob -> jid , pjob -> pid ) ; if ( ! deletejob ( jobs , pid ) ) { printf ( " \n " ) ; exit ( 1 ) ; } } else { printf ( " \n " ) ; exit ( 1 ) ; } } else if ( WIFEXITED ( status ) ) { if ( ! deletejob ( jobs , pid ) ) { printf ( " \n " ) ; exit ( 1 ) ; } } else { printf ( " \n " ) ; exit ( 1 ) ; } } else if ( pid == -1 && errno == EINTR ) { continue ; } else { break ; } } while ( 1 ) ; 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 .
// Status // pid // Pointer to job // Following directions from the link in the README // Using WNOHANG as spoken about in class // If stopped // get job and change state // changing state // Job was invalid // TODO: Find the link for the second tutorial // Delete job // DELETE JOB