ast_comparator/test/student_data/handout/shlab-handout/cases/prev_14_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.
 *
 * This will handle the child jobs. Remember that the jobs apart from the builtin ones
 * are carried by forking execing, so we'll have to reap the children processes.
 */
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.

This will handle the child jobs. Remember that the jobs apart from the builtin ones
are carried by forking execing, so we'll have to reap the children processes.
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 . This will handle the child jobs . Remember that the jobs apart from the builtin ones are carried by forking execing so we ' ll have to reap the children processes .
void sigchld_handler(int sig)
{ 
  pid_t pid;
  int status;
  struct job_t *job;
  while((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0) { 
    job = getjobpid(jobs, pid); 
    if (WIFSIGNALED(status)) { 
      printf("Job [%d] (%d) terminated by signal %d\n", job->jid, pid, WTERMSIG(status));
      deletejob(jobs, pid); 
    } else if (WIFSTOPPED(status)) { 
      printf("Job [%d] (%d) stopped by signal %d\n", job->jid, pid, WSTOPSIG(status));
      job->state = ST; 
    } else {
      deletejob(jobs, pid); 
    }
  }
  return;
}
void sigchld_handler ( int sig ) { pid_t pid ; int status ; struct job_t * job ; while ( ( pid = waitpid ( -1 , & status , WNOHANG | WUNTRACED ) ) > 0 ) { job = getjobpid ( jobs , pid ) ; if ( WIFSIGNALED ( status ) ) { printf ( " \n " , job -> jid , pid , WTERMSIG ( status ) ) ; deletejob ( jobs , pid ) ; } else if ( WIFSTOPPED ( status ) ) { printf ( " \n " , job -> jid , pid , WSTOPSIG ( status ) ) ; job -> state = ST ; } 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 .
//TODO5 // we don't want it hanging or traced. // get the job // terminated by ctrl-c // delete the terminated job // stopped by ctrl-z // make the job as stopped // else delete the terminated job. reap it.