/* * 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 */ void sigchld_handler(int sig) { pid_t pid; int status; struct job_t *job; if (verbose) printf("sigchld_handler: entering\n"); while ((pid = waitpid(-1,&status,WUNTRACED)) > 0){ job = jobs_getjobpid(pid); if (WIFEXITED(status)){ /*if job exited normally*/ printf("[%d] (%d) Terminated \t\t %s\n",job->jb_jid,pid,job->jb_cmdline); if(!jobs_deletejob(pid)) /* delete the job */ unix_error("error while deleting job"); } else if (WIFSTOPPED(status)){/*if job received a stop signal*/ job->jb_state = ST; /* change the job state */ printf("[%d] (%d) Suspended \t\t %s\n",job->jb_jid,pid,job->jb_cmdline); } else if (WIFSIGNALED(status)){/*if job was killed*/ printf("[%d] (%d) Killed \t\t %s\n",job->jb_jid,pid,job->jb_cmdline); if(!jobs_deletejob(pid)) /* delete the job */ unix_error("error while deleting job"); } if (verbose) printf("sigchld_handler: exiting\n"); 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. The handler reaps all * available zombie children */ void sigchld_handler(int sig) { struct job_t* job; int status, pid; if (verbose) printf("sigchld_handler: entering\n"); if ((pid = waitpid(-1,&status,WNOHANG | WUNTRACED)) == -1) pid = jobs_fgpid(); if (pid > 0) { job = jobs_getjobpid(pid); if (WIFSTOPPED(status)) { job->jb_state = ST; printf("[%d] (%d) : Stopped\n",job->jb_jid,job->jb_pid); } else if (WIFEXITED(status)) { printf("[%d] (%d) : Exited\n",job->jb_jid,job->jb_pid); jobs_deletejob(pid); } else if (WIFSIGNALED(status)) { printf("[%d] (%d) : Exited by User\n",job->jb_jid,job->jb_pid); jobs_deletejob(pid); } else { printf("Error on : [%d] (%d) - %s \n",job->jb_jid,job->jb_pid,job->jb_cmdline); } } if (verbose) printf("sigchld_handler: exiting\n"); return; }
/* do_kill - Execute the builtin kill command */ void do_kill(char **argv) { struct job_t * job; pid_t pid; if (verbose) printf("do_kill: entering\n"); job = treat_argv(argv); pid = job->jb_pid; assert(kill(-pid, SIGKILL) != -1); if (verbose) printf("do_kill: sigkill %d \n", pid); assert(jobs_deletejob(pid) != -1); if (verbose) printf("do_stop: exiting\n"); return; }