ast_comparator/test/student_data/handout/shlab-handout/cases/reference_24_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) 
{
  pid_t pid;
  int status;
  while((pid = waitpid(-1, &status, WNOHANG)) > 0)
  {
    int i;
    int jobindex = -1;
    for (i = 0; i < MAXJOBS; i++) 
    {
	if ((jobs[i].pid == pid) || (jobs[i].pid2 == pid) )
	{
	  jobindex = i;
	  break;
	}
    }
    if(jobs[jobindex].pid2!=0)
    {
      if(pid==jobs[jobindex].pid2)
      {
	kill(jobs[jobindex].pid,SIGTERM);
      }
      else
      {
	kill(jobs[jobindex].pid2,SIGTERM);
      }
    }
    if(WIFEXITED(status))
    {
      deletejob(jobs,pid);
    }
    else if(WIFSIGNALED(status))
    {
      deletejob(jobs,pid);
    }
    else if(WIFSTOPPED(status))
    {
    }
    else
    {
      deletejob(jobs,pid);
    }
  }
  return;
}
void sigchld_handler ( int sig ) { pid_t pid ; int status ; while ( ( pid = waitpid ( -1 , & status , WNOHANG ) ) > 0 ) { int i ; int jobindex = -1 ; for ( i = 0 ; i < MAXJOBS ; i ++ ) { if ( ( jobs [ i ] . pid == pid ) || ( jobs [ i ] . pid2 == pid ) ) { jobindex = i ; break ; } } if ( jobs [ jobindex ] . pid2 != 0 ) { if ( pid == jobs [ jobindex ] . pid2 ) { kill ( jobs [ jobindex ] . pid , SIGTERM ) ; } else { kill ( jobs [ jobindex ] . pid2 , SIGTERM ) ; } } if ( WIFEXITED ( status ) ) { deletejob ( jobs , pid ) ; } else if ( WIFSIGNALED ( status ) ) { deletejob ( jobs , pid ) ; } else if ( WIFSTOPPED ( status ) ) { } 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 .
//You will want to check for each of these conditions,  //in case the process has been stopped or  //terminated abruptly due to an unhandled signal,  //when you handle sigchld. //Wait without hanging to reap all children. //Get the job that goes with this pid //Find the job in the jobs list //Second process exists //If this pid is the second one //Kill the first one //If this pid is the first one //Kill the second one //printf("Child with pid %d exited normally.\n", pid); //Remove child from list //printf("Child with pid %d exited because of uncaught signal number %d.\n", pid, WTERMSIG(status)); //Remove child from list //Do something here? //printf("Child with pid %d is stopped.\n", pid);      //printf("Child with pid %d was reaped for an unknown reason.\n", pid); //Remove child from list