void signalHandler_child(int p) { pid_t pid; int terminationStatus; pid = waitpid(WAIT_ANY, &terminationStatus, WUNTRACED | WNOHANG); if (pid > 0) { t_job* job = getJob(pid, BY_PROCESS_ID); if (job == NULL) return; if (WIFEXITED(terminationStatus)) { if (job->status == BACKGROUND) { printf("\n[%d]+ Done\t %s\n", job->id, job->name); jobsList = delJob(job); //shellPrompt(); //printf("myShell> "); } } else if (WIFSIGNALED(terminationStatus)) { printf("\n[%d]+ KILLED\t %s\n", job->id, job->name); jobsList = delJob(job); //shellPrompt(); //printf("myShell> "); } else if (WIFSTOPPED(terminationStatus)) { if (job->status == BACKGROUND) { tcsetpgrp(MSH_TERMINAL, MSH_PGID); changeJobStatus(pid, WAITING_INPUT); printf("\n[%d]+ suspended [wants input]\t %s\n", numActiveJobs, job->name); //shellPrompt(); //printf("myShell> "); } else { tcsetpgrp(MSH_TERMINAL, job->pgid); changeJobStatus(pid, SUSPENDED); printf("\n[%d]+ stopped\t %s\n", numActiveJobs, job->name); //shellPrompt(); //printf("myShell> "); } return; } else { if (job->status == BACKGROUND) { jobsList = delJob(job); } } tcsetpgrp(MSH_TERMINAL, MSH_PGID); } }
void waitJob(t_job* job) { int terminationStatus; while (waitpid(job->pid, &terminationStatus, WNOHANG) == 0) { if (job->status == SUSPENDED) return; } jobsList = delJob(job); }
/** * waits for a job, blocking unless it has been suspended. * Deletes the job after it has been executed */ void waitJob(t_job* job) { int terminationStatus; while (waitpid(job->pid, &terminationStatus, WNOHANG) == 0) { // while there are child to be waited if (job->status == SUSPENDED) // exit if the job has been set to be stopped return; } jobsList = delJob(job); // delete the job }
/** * signal handler for SIGCHLD */ void signalHandler_child(int p) { pid_t pid; int terminationStatus; pid = waitpid(WAIT_ANY, &terminationStatus, WUNTRACED | WNOHANG); // intercept the process that sends the signal if (pid > 0) { // if there are information about it t_job* job = getJob(pid, BY_PROCESS_ID); // get the job from the list if (job == NULL) return; if (WIFEXITED(terminationStatus)) { // case the process exits normally if (job->status == BACKGROUND) { // child in background terminates normally printf("\n[%d]+ Done\t %s\n", job->id, job->name); // inform the user jobsList = delJob(job); // delete it from the list } } else if (WIFSIGNALED(terminationStatus)) { // the job dies because of a signal printf("\n[%d]+ KILLED\t %s\n", job->id, job->name); // inform the user jobsList = delJob(job); // delete the job from the list } else if (WIFSTOPPED(terminationStatus)) { // a job receives a SIGSTP signal if (job->status == BACKGROUND) { // the job is in bg tcsetpgrp(RSH_TERMINAL, RSH_PGID); changeJobStatus(pid, WAITING_INPUT); // change its status to "waiting for input" printf("\n[%d]+ suspended [wants input]\t %s\n", numActiveJobs, job->name); // inform the user } else { // otherwise, the job is going to be suspended tcsetpgrp(RSH_TERMINAL, job->pgid); changeJobStatus(pid, SUSPENDED); // we modify the status printf("\n[%d]+ stopped\t %s\n", numActiveJobs, job->name); // and inform the user } return; } else { if (job->status == BACKGROUND) { // otherwise, delete the job from the list jobsList = delJob(job); } } tcsetpgrp(RSH_TERMINAL, RSH_PGID); } }