/* print information about finished jobs */ void CheckJobs() { bgjobL *temp = donejobs; if (temp == NULL) return; do { temp->commands[strlen(temp->commands)] = 0; temp->commands[strlen(temp->commands) -1] = 0; printf("[%d] Done %s\n", temp->status, temp->commands); fflush(stdout); temp = temp->next; } while(temp != NULL); temp = donejobs; //remove from list after printing info do { RemoveJob(temp, DONEJOBL, 0); temp = donejobs; } while (temp != NULL); donejobs = NULL; }
/* * main * * arguments: * int argc: the number of arguments provided on the command line * char *argv[]: array of strings provided on the command line * * returns: int: 0 = OK, else error * * This sets up signal handling and implements the main loop of tsh. */ int main(int argc, char *argv[]) { /* Initialize command buffer */ char* cmdLine = malloc(sizeof(char*) * BUFSIZE); /* shell initialization */ if (signal(SIGINT, sig) == SIG_ERR) PrintPError("SIGINT"); if (signal(SIGTSTP, sig) == SIG_ERR) PrintPError("SIGTSTP"); while (!forceExit) /* repeat forever */ { char* prompt = getenv("PS1"); if (prompt != NULL) { printf("%s", prompt); } /* read command line */ getCommandLine(&cmdLine, BUFSIZE); if (strcmp(cmdLine, "exit") == 0) forceExit = TRUE; /* checks the status of background jobs */ if (!forceExit) { CheckJobs(); } /* interpret command and line * includes executing of commands */ Interpret(cmdLine); } bgjobL* curr = bgjobs; while (curr != NULL) { curr = bgjobs; int status; int res = waitpid(curr->pid, &status, WNOHANG | WUNTRACED | WCONTINUED); if (!(res == curr->pid && !WIFCONTINUED(status))) { kill(curr->pid, SIGKILL); } RemoveJob(curr->jid); } /* shell termination */ free(cmdLine); return 0; } /* main */
/* bring background job to foreground */ static void fg_func(commandT* cmd){ if (cmd->argc > 2) { PrintPError("Error: fg only takes one or no arguments"); return; } if (bgjobs != NULL) { bgjobL *temp; if (cmd->argc == 1) temp = GetMostRecentJob(); else if (FindJobId(atoi(cmd->argv[1]))) temp = FindJobId(atoi(cmd->argv[1])); else { PrintPError("Error: job ID not found"); return; } fgpid = temp->pid; strcpy(fgcommands, temp->commands); //copy bg job cmdline to global fgcommands variable if (fgcommands[strlen(fgcommands) -1] == '&') //remove & { fgcommands[strlen(fgcommands) -1] = '\0'; } if (temp->status == STOPPED) //send SIGCONT if bg job was stopped kill(-fgpid, SIGCONT); if (!RemoveJob(temp, BGJOBL, 1)) //remove from ll PrintPError("Error: Not a job"); fgstatus = RUNNING; while (fgstatus) //wait for sigchld { sleep(1); } } }
void CPartFileConvertDlg::RemoveSel() { if (joblist.GetSelectedCount()==0) return; ConvertJob* job; POSITION pos = joblist.GetFirstSelectedItemPosition(); while(pos != NULL) { int index = joblist.GetNextSelectedItem(pos); if(index > -1) { job=(ConvertJob*)joblist.GetItemData(index); if (job->state != CONV_INPROGRESS) { RemoveJob(job); // from list CPartFileConvert::RemoveJob(job); pos = joblist.GetFirstSelectedItemPosition(); } } } }
static void sig(int signo) { if (signo == SIGINT) { if (fgpid) { kill(-fgpid, SIGINT); //send sigint to foreground job //printf("\n"); } } if (signo == SIGCHLD) { int status; pid_t chldpid; chldpid = waitpid(-1, &status, WUNTRACED | WNOHANG); ///wait on child if (chldpid == fgpid) //sigchld send from foreground process { fgstatus = STOPPED; } else if (WIFEXITED(status) || WIFSIGNALED(status)) //sigchld send from bg { if (FindJobPid(chldpid) == NULL) //not in bgjobl return; //get id, print message if bg job terminated with error int id = FindIdPid(chldpid); if (WIFSIGNALED(status)) //terminated with error { printf("[%d] terminated with status %d PID: %d\n", id, WTERMSIG(status), chldpid); //fflush(stdout); } //remove finished bg job from list, put in done jobs if (!RemoveJob(FindJobPid(chldpid), BGJOBL, 0)) PrintPError("SIGCHLD from child failed"); } } if (signo == SIGTSTP) //sigstp signal encountered, add foreground job to bgjobs ll { if (fgpid != 0) { int id; if (GetMostRecentJob() == NULL) id = 1; else { bgjobL *temp; temp = GetMostRecentJob(); //get most recent bg job id = FindIdPid(temp->pid); //use its pid to find id, increment to get id of new bg job id++; } printf("[%d] Stopped %s\n", id, fgcommands); fflush(stdout); int i = AddJob(fgpid, STOPPED, fgcommands, BGJOBL); //add stopped job to bgjobl kill(-fgpid, SIGTSTP); if (i == 0) { PrintPError("Error adding job"); } } } }
static void RunBuiltInCmd(commandT* cmd) { // Execute cd if(!strcmp(cmd->argv[0],"cd")) { if(cmd->argc==1) { int ret = chdir(getenv("HOME")); if(ret == -1) { // fprintf(stdout, "Error changing directory with command: %s\n", cmd->cmdline); } } else { int ret = chdir(cmd->argv[1]); if(ret == -1) { // fprintf(stdout, "Error changing directory with command: %s\n", cmd->cmdline); } } } // Execute env variable assignments else if (strchr(cmd->argv[0],'=')) { char* var = strtok(cmd->argv[0],"="); char* val = strtok(NULL,"="); setenv(var,val,1); } // Execute bg else if (strcmp(cmd->argv[0], "bg") == 0) { struct bgjob_l* jobPointer = bgjobs; if(jobPointer != NULL) { // find most recent job if(cmd->argc < 2) { while(jobPointer->next != NULL) { jobPointer = jobPointer->next; } } else { int i; // find indicated job printf("cmd-> argv[1] = %s\n", cmd->argv[1]); printf("(int)*cmd->argv[1] = %d\n", (int)*cmd->argv[1]); for(i = 1; i < (int)*cmd->argv[1]; i++) { jobPointer = jobPointer->next; } } kill(jobPointer->pid, SIGCONT); // resume job } } // Execute jobs else if (strcmp(cmd->argv[0], "jobs") == 0) { struct bgjob_l* jobPointer = bgjobs; int i = 1; if(jobPointer != NULL) { while(jobPointer != NULL) { printf("[%d] %-24s%s%s\n", jobPointer->id, jobPointer->status, jobPointer->cmdline, strcmp(jobPointer->status, "Running") == 0 ? "&" : ""); fflush(stdout); i++; jobPointer = jobPointer->next; } removeCompletedJobs(); } else { // fprintf(stdout, "jobPointer is null\n"); } } // Execute fg else if (!strcmp(cmd->argv[0], "fg")){ struct bgjob_l* jobPointer = bgjobs; // tcsetpgrp()??? if(jobPointer != NULL) { // find most recent job if(cmd->argc < 2) { while(jobPointer->next != NULL) { jobPointer = jobPointer->next; } } else { // find indicated job int i; for(i = 1; i < (int)*cmd->argv[1]; i++) { jobPointer = jobPointer->next; } } fgpid = jobPointer->pid; kill(jobPointer->pid, SIGCONT); stopped = 0; wait_fg(); RemoveJob(fgpid); } } }