ast_comparator/test/student_data/handout/shlab-handout/cases/32_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;
	struct job_t *curr;
	while(1){
		pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
		if(pid > 0){
			if(WIFEXITED(status)){
				deletejob(jobs, pid);
			} else if(WIFSIGNALED(status)){
				printf("Job [%d] (%d) terminated by signal %d\n", pid2jid(pid), pid, WTERMSIG(status));
				deletejob(jobs, pid);
			} else if(WIFSTOPPED(status)){
				curr = getjobpid(jobs, pid);
				curr->state = ST;
				printf("Job [%d] (%d) stopped by signal %d\n", pid2jid(pid), pid, WSTOPSIG(status));
			}
		}
		if(pid < 0){
			if(errno != ECHILD)
				unix_error("wiatpid error");
			break;
		}
		if(pid == 0)
			break;
	}
  return;
}
void sigchld_handler ( int sig ) { pid_t pid ; int status ; struct job_t * curr ; while ( 1 ) { pid = waitpid ( -1 , & status , WNOHANG | WUNTRACED ) ; if ( pid > 0 ) { if ( WIFEXITED ( status ) ) { deletejob ( jobs , pid ) ; } else if ( WIFSIGNALED ( status ) ) { printf ( " \n " , pid2jid ( pid ) , pid , WTERMSIG ( status ) ) ; deletejob ( jobs , pid ) ; } else if ( WIFSTOPPED ( status ) ) { curr = getjobpid ( jobs , pid ) ; curr -> state = ST ; printf ( " \n " , pid2jid ( pid ) , pid , WSTOPSIG ( status ) ) ; } } if ( pid < 0 ) { if ( errno != ECHILD ) unix_error ( " " ) ; break ; } if ( pid == 0 ) break ; } 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 .
/* WNOHANG: return immediately if no child has exited
		 * WUNTRACED: also return if a child has stopped, not only terminated */ /* -1: wait for any child process */ /* if terminated noramlly, reap the zombie */ /* if terminated by signal */ /* if stopped by signal */ /* on error, -1 is returned */ /* if WNOHANG was specified and one or more child(ren) specified by
		 * pid exist, but have not yet changed state, then 0 is returned */