/* * CheckJobs * * arguments: none * * returns: none * * Checks the status of running jobs. */ void CheckJobs() { bgjobL* temp = donejobs; // grab header if (temp == NULL) // no one in list return; do { temp->commands[strlen(temp->commands)] = 0; temp->commands[strlen(temp->commands) - 1] = 0; // rid the ampersand printf("[%d] Done %s\n", temp->status, temp->commands); //status doubling as index fflush(stdout); temp = temp->next; } while (temp != NULL); temp = donejobs; do { removejob(temp, _DONELIST, 0); temp = donejobs; } while (temp != NULL); donejobs = NULL; } /* CheckJobs */
void printjobs(struct job ** head) { int i = 0; int status; struct job * current = *head; // check if any job need to be printed if (current == NULL) { printf("No job in background.\n"); } else{ printf("Jobs PID\tStatus\t\tJobs\n----------------------------------------------------------\n"); } while (current != NULL) { // print pid printf("%i\t\t", current->pid); // print status int pid = current->pid; waitpid(pid, &status, WNOHANG); if(waitpid(pid, &status, WNOHANG) == -1){ printf("Done\t\t"); } else { printf("Working\t\t"); } // print cmd int j = 0; while(current->args[j] != NULL){ printf("%s\t", current->args[j]); j++; } printf("\n"); // check if the process is terminated // if it is it is removed from the jobs list current = current->next; if(waitpid(pid, &status, WNOHANG) == -1){ removejob(head, pid); } } }
/* * RunBuiltInCmd * * arguments: * commandT *cmd: the command to be run * * returns: none * * Runs a built-in command. */ static void RunBuiltInCmd(commandT* cmd) { if (strcmp(cmd->argv[0], "pwd") == 0) { if (cmd->argc != 1) //something other than just pwd entered PrintPError("The command pwd takes no arguments."); else Print(currentdir); } if (strcmp(cmd->argv[0], "cd") == 0) //cd needs to account for no argument, absolutes, and .. { // use cmd->argc (number or args including command cd) to switch between cases if (cmd->argc >= 3) // too many args PrintPError("The command cd takes one argument."); else if (cmd->argc == 1) // no arguments given, chdir to HOME directory { if (chdir(getenv("HOME")) < 0) PrintPError("Could not change directory."); } else if (*cmd->argv[1] == '/') // absolute path { if (chdir(cmd->argv[1]) < 0) PrintPError("Could not change directory."); } else if (*cmd->argv[1] == '.' && cmd->argv[1][1] == '.') // go back directories { char* tempPtr; tempPtr = cmd->argv[1]; // ptr to walk over argument counting how many directories to go back while (*tempPtr != '\0') // kind of a weak way to count, since we assume the user is putting periods { if (*tempPtr == '/') // skip the slashes tempPtr++; else { tempPtr += 2; if (chdir("..") < 0) //go back one directory PrintPError("Could not change directory."); } } } else // argument without . or / so chdir to currentdir + it { char* temp = (char*)malloc(500*sizeof(char)); strcpy(temp, currentdir); strcat(temp, "/"); strcat(temp, cmd->argv[1]); if (chdir(temp) < 0) PrintPError("Could not change directory."); free(temp); } } if (strcmp(cmd->argv[0], "jobs") == 0) { bgjobL* temp = bgjobs; while (temp != NULL) { if (temp->status) // running { char* commands = (char*)malloc(500*sizeof(char)); strcpy(commands, temp->commands); if (commands[strlen(commands) - 1] != '&') strcat(commands, " &"); printf("[%d] Running %s\n", temp->index, commands); fflush(stdout); free(commands); } else { //char* commands = (char*)malloc(500*sizeof(char)); //strcpy(commands, temp->commands); printf("[%d] Stopped %s\n", temp->index, temp->commands); fflush(stdout); //free(commands); } temp = temp->next; } } if (strcmp(cmd->argv[0], "bg") == 0) { if (cmd->argc > 2) // too many args { PrintPError("bg takes one or no arguments"); return; } //sigset_t chldsigset; // Initialize and set sigset for procmask //sigemptyset(&chldsigset); //sigaddset(&chldsigset, SIGCHLD); //sigprocmask(SIG_BLOCK, &chldsigset, NULL); // mask SIGCHLDs if (bgjobs != NULL) { bgjobL* temp; if (cmd->argc == 1) // default temp = getmostrecentjob(); else if (findjobindex(atoi(cmd->argv[1]))) temp = findjobindex( atoi(cmd->argv[1]) ); else { PrintPError("Index outside of job bounds"); return; } pid_t pid = temp->pid; kill(-pid, SIGCONT); // Send SIGCONT to the job and all processes temp->status = _RUNNING; // Set status to running //sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); //unmask } } if (strcmp(cmd->argv[0], "fg") == 0) { if (cmd->argc > 2) // too many args { PrintPError("fg takes one or no arguments"); return; } //sigset_t chldsigset; // Initialize and set sigset for procmask //sigemptyset(&chldsigset); //sigaddset(&chldsigset, SIGCHLD); //sigprocmask(SIG_BLOCK, &chldsigset, NULL); // mask SIGCHLDs if (bgjobs != NULL) { bgjobL* temp; if (cmd->argc == 1) // default temp = getmostrecentjob(); else if (findjobindex(atoi(cmd->argv[1]))) temp = findjobindex( atoi(cmd->argv[1]) ); else { PrintPError("Index outside of job bounds"); return; } fgpid = temp->pid; // set fg to pid of job strcpy(fgcommands, temp->commands); // copy commands to fgcommands fgcommands[strlen(fgcommands) - 1] = 0; if (temp->status == _STOPPED) // if stopped, SIGCONT it to get it running again kill(-fgpid, SIGCONT); // remove from job list if ( !removejob(temp, _JOBLIST, 1) ) PrintPError("Not a job"); //sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); //unmask fgstatus = _RUNNING; // Now wait on it with a busy loop while (fgstatus) { sleep(1); } } } if (strcmp(cmd->argv[0], "alias") == 0){ aliasL* temp=aliaslist; aliasL* previousalias=aliaslist; if(cmd->argc==1)/* show all the alias */ { if (temp == NULL) // start of list { ; } else // something at start of list { while (TRUE) { if(temp!=NULL){ int i; for( i = 0; temp->aliascmdline[i] != 0; ++i) { if(i==0)printf("alias "); putchar(temp->aliascmdline[i]); if(temp->aliascmdline[i]=='=')putchar('\''); if(temp->aliascmdline[i+1]==0)puts("\'"); } //printf("alias %s\n",temp->aliascmdline); } if (temp->next == NULL) { break; } temp = temp->next; } } } else{ aliasL* newalias = malloc(sizeof(aliasL)); // malloc memory for new alias if (newalias == NULL){ PrintPError("Error in allocating memory for alias"); return; } // Initialize new alias newalias->aliascmdline = (char*)malloc(strlen(cmd->argv[1]+1)); if (newalias->aliascmdline == NULL){ PrintPError("Error in allocating memory for alias"); return; } strcpy(newalias->aliascmdline, cmd->argv[1]); newalias->next = NULL; if (temp == NULL) // start of list { aliaslist=newalias; } else // something at start of list { while (TRUE) { if(strcmp(cmd->argv[1],temp->aliascmdline)<=0)//we find the small one, so insert it { if( previousalias!=aliaslist)previousalias->next=newalias; newalias->next=temp; if( previousalias==aliaslist)aliaslist=newalias; break; } else if (temp->next == NULL) { temp->next = newalias; break; } previousalias = temp; temp = temp->next; } } } } if (strcmp(cmd->argv[0], "unalias") == 0){ aliasL* temp=aliaslist; aliasL* previousalias=aliaslist; if(cmd->argc==1)// do nothing { ; } else { while (TRUE) { if( ( temp != NULL ) && (strncmp(cmd->argv[1],temp->aliascmdline,strlen(cmd->argv[1]))==0) )// we find the alias, so unalias it { previousalias->next = temp->next; if(temp==aliaslist)aliaslist=temp->next; free(temp->aliascmdline); free(temp); break; } if ( ( temp == NULL ) || (temp->next == NULL) ) { printf("%s: unalias: %s: not found\n",SHELLNAME,cmd->argv[1]); //PrintPError(cmd->argv[1]); break; } previousalias = temp; temp = temp->next; } } } } /* RunBuiltInCmd */