/* execute build in command bg - send fg job to bg*/ static void bg_func(commandT* cmd){ if (cmd->argc > 2) { PrintPError("Error: bg only takes one or no arguments"); } if(bgjobs != NULL) { bgjobL *temp; if (cmd->argc == 1)//get most recent job temp = GetMostRecentJob(); else if (FindJobId(atoi(cmd->argv[1]))) temp = FindJobId(atoi(cmd->argv[1])); //find job in list else { PrintPError("Error: job ID not found"); return; } pid_t pid = temp->pid; kill(-pid, SIGCONT); //send SIGCONT to job and all processes temp->status = RUNNING; } }
/* * Exec * * arguments: * commandT *cmd: the command to be run * bool forceFork: whether to fork * * returns: none * * Executes a command. */ static void Exec(commandT* cmd, bool forceFork) { if (forceFork) { // Do this if you should fork int pid; sigset_t x; sigemptyset (&x); sigaddset(&x,SIGCHLD); if (sigprocmask(SIG_BLOCK,&x,NULL) != 0) { PrintPError("Signal Block Failure"); } if ((pid = fork()) < 0) { // fork returns negative if it fails. PrintPError("Fork failed"); } else { if (pid == 0) { // Child - to exec setpgid(0,0); // remove from foreground process group argZeroConverter(cmd); sigprocmask(SIG_UNBLOCK,&x,NULL); execv(cmd->name,cmd->argv); PrintPError("Execv failed"); } else { // Parent - wait for child to be reaped. fgpid = pid; // foreground process id int * status = malloc(sizeof(int)); int * freethis = status; waitpid(pid,status,0); fgpid = 0; free(freethis); } } free(cmd->name); } } /* Exec */
int main (int argc, char *argv[]) { /* Initialize command buffer */ char* cmdLine = malloc(sizeof(char*)*BUFSIZE); /* shell initialization */ if (signal(SIGINT, sig_handler) == SIG_ERR) PrintPError("SIGINT"); if (signal(SIGTSTP, sig_handler) == SIG_ERR) PrintPError("SIGTSTP"); while (!forceExit) /* repeat forever */ { /* read command line */ getCommandLine(&cmdLine, BUFSIZE); if(strcmp(cmdLine, "exit") == 0) { forceExit=TRUE; continue; } //printf("after exit\n"); /* checks the status of background jobs */ //if(strcmp(cmdLine, "jobs") != 0){ CheckJobs(); //printf("after checkjobs\n"); //} /* interpret command and line * includes executing of commands */ Interpret(cmdLine); } /* shell termination */ free(cmdLine); return 0; } /* end main */
/* * RunCmdRedirOut * * arguments: * commandT *cmd: the command to be run * char *file: the file to be used for standard output * * returns: none * * Runs a command, redirecting standard output to a file. */ void RunCmdRedirOut(commandT* cmd, char* file) { int standardout = dup(1); int fileout = open(file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH); //write only. if not exists, create it. if exists, delete it. rwxr--r-- if(fileout < 0){ PrintPError("OpenOutFile"); return; } close(1); //close standard output if(dup(fileout) != 1){ PrintPError("DupOutFile"); return; } close(fileout); RunCmd(cmd); close(1); //close redir out, and back to normal if(dup(standardout)!=1){ PrintPError("DupStdOutFile"); return; } } /* RunCmdRedirOut */
/* * RunCmdRedirIn * * arguments: * commandT *cmd: the command to be run * char *file: the file to be used for standard input * * returns: none * * Runs a command, redirecting a file to standard input. */ void RunCmdRedirIn(commandT* cmd, char* file) { int standardin = dup(0); int filein = open(file, O_RDONLY); //write only. if not exists, create it. if exists, delete it. rwxr--r-- if(filein < 0){ PrintPError("OpenInFile"); return; } close(0); //close standard output if(dup(filein) != 0){ PrintPError("DupInFile"); return; } close(filein); RunCmd(cmd); close(0); //close redir out, and back to normal if(dup(standardin)!=0){ PrintPError("DupStdInFile"); return; } } /* RunCmdRedirIn */
static void Exec(commandT* cmd, bool forceFork) { pid_t pid; //create sigset containing sigchld sigset_t chldsigset; sigemptyset(&chldsigset); sigaddset(&chldsigset, SIGCHLD); sigprocmask(SIG_BLOCK, &chldsigset, NULL); //fork child process pid = fork(); if (pid >= 0) { if (pid == 0) //execute cmd, exit child { setpgid(0,0); sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); if (execv(cmd->name, cmd->argv) < 0) { PrintPError("Error in executing the command"); } exit(0); } else { if (!cmd->bg) //foreground, wait for foreground to finish { fgpid = pid; strcpy(fgcommands, cmd->cmdline); fgstatus = RUNNING; sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); while (fgstatus) sleep(1); } else //background { char * ampersand = "&"; strcat(cmd->cmdline, ampersand); int jobnumber = AddJob(pid, RUNNING, cmd->cmdline, BGJOBL); if (jobnumber == 0) PrintPError("error adding job"); sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); } } } else { PrintPError("Error in fork"); } }
int main (int argc, char *argv[]) { /* Initialize command buffer */ char* cmdLine = malloc(sizeof(char*)*BUFSIZE); fgcommands = (char *) malloc(500 * sizeof(char)); /* shell initialization */ if (signal(SIGINT, sig) == SIG_ERR) PrintPError("SIGINT"); if (signal(SIGTSTP, sig) == SIG_ERR) PrintPError("SIGTSTP"); if (signal(SIGCHLD, sig) == SIG_ERR) PrintPError("SIGCHLD"); // printPrompt(); while (!forceExit) /* repeat forever */ { //printPrompt(); /* read command line */ getCommandLine(&cmdLine, BUFSIZE); //cmdLine = strdup(checkAlias2(cmdLine)); //printf("The new is %s\n", cmdLine); if(strcmp(cmdLine, "exit") == 0 ) { forceExit=TRUE; continue; } else if (feof(stdin)){ //printf("\n"); forceExit = TRUE; break; } fgpid = 0; /* checks the status of background jobs */ CheckJobs(); /* interpret command and line * includes executing of commands */ Interpret(cmdLine); //fflush(stdout); fgpid = 0; } /* shell termination */ free(cmdLine); free(fgcommands); return 0; } /* end main */
/* * 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 */
int main (int argc, char *argv[]) { /* Initialize command buffer */ char* cmdLine = malloc(sizeof(char*)*BUFSIZE); /* shell initialization */ if (signal(SIGINT, sig_handler) == SIG_ERR) PrintPError("SIGINT"); if (signal(SIGTSTP, sig_handler) == SIG_ERR) PrintPError("SIGTSTP"); while (TRUE) /* repeat forever */ { /* print prompt */ printf("%%"); //printf("my status: %d", waitpid(getpid(), &status, WNOHANG)); //printf("%%"); /* read command line */ getCommandLine(&cmdLine, BUFSIZE); if(strcmp(cmdLine, "exit") == 0 || feof(stdin)) { forceExit=TRUE; break; } else { // If we juse printf(cmdLine), compiler gives a warning because the cmdLine can contain things like %s // and the program will try to find some string that does not exist. This could be exploited to run virus. //fprintf(stderr, "%s", cmdLine); } /* checks the status of background jobs */ CheckJobs(); /* interpret command and line * includes executing of commands */ Interpret(cmdLine); } // make sure all the shell's child processes are terminated if (forceExit == TRUE) { while (bgjobs != NULL) { kill(bgjobs->pid, SIGINT); bgjobs = bgjobs->next; } } /* shell termination */ free(cmdLine); return 0; } /* end main */
/* * 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],"echo") == 0) { // runs command echo int i; for(i = 1; i < cmd->argc; i++) { printf("%s ",cmd->argv[i]); } PrintNewline(); } if (strcmp(cmd->argv[0],"cd") == 0) { // runs command cd int dir = 0; if (cmd->argc > 1) { dir = chdir(cmd->argv[1]); } else { dir = chdir(getenv("HOME")); } //0 if success, -1 if failure if (dir != 0) { PrintPError("cd error"); } } if (strcmp(cmd->argv[0],"exit") == 0) { // escapes if command is exit return; } } /* RunBuiltInCmd */
/* 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); } } }
char * getFullPath(char * name) { bool found = FALSE; char * pathlist = getenv("PATH"); // prepare the memory for the possible paths char * home = getenv("HOME"); char * homeCopy = malloc(MAXPATHLEN*sizeof(char*)); strcpy(homeCopy,home); char * pathCopy = malloc(MAXPATHLEN*sizeof(char*)); strcpy(pathCopy,pathlist); char * result = malloc(MAXPATHLEN*sizeof(char*)); // prepare memory to store the result char * current = getCurrentWorkingDir(); strcat(homeCopy,"/"); strcat(homeCopy,name); if (name[0] == '/') { // if it is an absolute path, store result. if (doesFileExist(name)) { strcpy(result,name); found = TRUE; } } else { if (doesFileExist(homeCopy)) { // If it is in the home directory strcpy(result,homeCopy); found = TRUE; } else { strcat(current,"/"); strcat(current,name); if (doesFileExist(current)) { // If it is in the current directory strcpy(result,current); found = TRUE; } else { // Else, check every path in PATH environment variable char* fullpath = strtok(pathCopy, ":"); while (fullpath != NULL) { char * path = malloc(MAXPATHLEN*sizeof(char*)); strcpy(path,fullpath); strcat(path,"/"); if (doesFileExist(strcat(path,name))) { strcpy(result,path); found = TRUE; } fullpath = strtok(NULL, ":"); free(path); } } } } free(current); free(pathCopy); free(homeCopy); if (found) { return result; } else { free(result); PrintPError(name); return NULL; } } /* getFullPath */
/* * RunCmdPipe * * arguments: * commandT *cmd1: the commandT struct for the left hand side of the pipe * commandT *cmd2: the commandT struct for the right hand side of the pipe * * returns: none * * Runs two commands, redirecting standard output from the first to * standard input on the second. */ void RunCmdPipe(commandT* cmd1, commandT* cmd2) { int pipefp[2]; int standardout = dup(1); int standardin = dup(0); if(pipe(pipefp)==-1)PrintPError("Pipe Create Error"); /* redirect the cmd1 output to pipe */ close(1); //close standard output if(dup(pipefp[1]) != 1){ PrintPError("Pipe Write"); return; } close(pipefp[1]); RunCmd(cmd1); close(1); //close redir out, and back to normal if(dup(standardout)!=1){ PrintPError("DupStdOutFile"); return; } /* redirect the pipe to cmd2 input */ close(0); //close standard output if(dup(pipefp[0]) != 0){ PrintPError("Pipe read"); return; } close(pipefp[0]); RunCmd(cmd2); close(0); //close redir out, and back to normal if(dup(standardin)!=0){ PrintPError("DupStdInFile"); return; } } /* RunCmdPipe */
/* * 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"); /* Terminated or stopped child */ while (!forceExit) /* repeat forever */ { /*Insert tsh$ prompt*/ printPrompt(); /* read command line */ getCommandLine(&cmdLine, BUFSIZE); if (strcmp(cmdLine, "exit") == 0) forceExit = TRUE; /* checks the status of background jobs */ if(!forceExit){ CheckJobs(); fflush(NULL); } /* interpret command and line * includes executing of commands */ Interpret(cmdLine); fflush(NULL); //getPath(); } /* shell termination */ free(cmdLine); return 0; } /* main */
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"); if (signal(SIGCONT, sig) == SIG_ERR) PrintPError("SIGCONT"); if (signal(SIGCHLD, sigHandler) == SIG_ERR) PrintPError("SIGCHLD"); while (!forceExit) /* repeat forever */ { printPrompt(); /* read command line */ getCommandLine(&cmdLine, BUFSIZE); // strcmp: string compare if(strcmp(cmdLine, "exit") == 0) { forceExit=TRUE; continue; } /* checks the status of background jobs */ CheckJobs(); /* interpret command and line * includes executing of commands */ Interpret(cmdLine); } /* shell termination */ free(cmdLine); releaseAlias(aliasList); /* print all lists and check printf("\n\n ---------TERMINATE SHELL--------\n"); printf("Alias:\n"); printAlias();*/ return 0; } /* end main */
/* handles redirect in */ void RunCmdRedirIn(commandT* cmd, char* file) { //rcreate file, set inputstream to file int stdin = dup(0); int filein = open(file, O_RDONLY); close(0); if ( dup(filein) != 0) { PrintPError("Error dup filein: "); return; } close(filein); //run cmd with file as input RunCmd(&cmd, 1); close(0); //set input back to stdin if (dup(stdin) != 0) { PrintPError("Error dup stdin: "); return; } }
/* handles redirect out */ void RunCmdRedirOut(commandT* cmd, char* file) { //create file, set ouputsrtream to file int stdout = dup(1); int fileout = open(file, O_TRUNC | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); close(1); if (dup(fileout) != 1) { PrintPError("Error dup fileout: "); return; } close(fileout); //RunCmd with outputream as file RunCmd(&cmd, 1); close(1); //reset to stdout if (dup(stdout) != 1) { PrintPError("Error dup stdout: "); return; } }
/* * Job Functions */ int addjob(pid_t jobpid, int jobstatus, char* jobcommands, int whichlist) // Makes and adds job to the job list or done list and returns index of job { int i = getnewindex(); // grab what the index should be bgjobL* temp; if (whichlist == _JOBLIST) temp = bgjobs; // temporary header else temp = donejobs; bgjobL* newJob = malloc(sizeof(bgjobL)); // malloc memory for new job if (newJob == NULL) PrintPError("Error in allocating memory for job"); // Initialize new job newJob->pid = jobpid; newJob->status = jobstatus; newJob->commands = (char*)malloc(500*sizeof(char)); newJob->index = i; strcpy(newJob->commands, jobcommands); newJob->next = NULL; if (temp == NULL) // start of list { if (whichlist == _JOBLIST) bgjobs = newJob; // move header else donejobs = newJob; return i; } else // something at start of list { while (TRUE) { if (temp->next == NULL) { temp->next = newJob; break; } temp = temp->next; } return i; } }
/* * RunCmdFork * * arguments: * commandT *cmd: the command to be run * bool fg: whether to fg * * returns: none * * Runs a command, switching between built-in and external mode * depending on cmd->argv[0] */ void RunCmdFork(commandT* cmd, bool fg) { if (cmd->argc <= 0) return; if (IsBuiltIn(cmd->argv[0])) { RunBuiltInCmd(cmd); } else if (ResolveExternalCmd(cmd)) { RunExternalCmd(cmd, fg); } else { char* temp = (char*)malloc(500*sizeof(char)); char* unfoundCommand = cmd->argv[0]; char* unresolvedCommand = "line 1: "; // does line 1 refer to error in first argument? strcpy(temp, unresolvedCommand); strcat(temp, unfoundCommand); PrintPError(temp); free(temp); } } /* RunCmdFork */
/* * 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 */
/* * Exec * * arguments: * commandT *cmd: the command to be run * bool fg: whether to fg * * returns: none * * Executes a command. */ void Exec(commandT* cmd, bool fg) { // Fork and execute the command using filedir as command and cmd->argv as arguments int pid; sigset_t chldsigset; // Initialize and set sigset for procmask sigemptyset(&chldsigset); sigaddset(&chldsigset, SIGCHLD); sigprocmask(SIG_BLOCK, &chldsigset, NULL); // mask SIGCHLDs char* commands = (char*)malloc(500*sizeof(char)); int i = 0; while (cmd->argv[i] != 0) // traverse commands and copy into one new jobcommands string { int j = 0; int insertquotes = 0; while (cmd->argv[i][j] != 0) { if (cmd->argv[i][j] == ' ') // if there are spaces in a single command insertquotes = 1; j++; } if (i == 0) strcpy(commands, cmd->argv[i]); else { strcat(commands, " "); if (insertquotes) strcat(commands, "\""); strcat(commands, cmd->argv[i]); if (insertquotes) strcat(commands, "\""); } i++; } pid = fork(); if (pid >= 0) // fork succeeds { if (pid == 0) // child process { setpgid(0,0); // Unblock SIGCHLD first sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); // Child will execv the command if (execv(filedir, cmd->argv) < 0) PrintPError("Error in executing the command"); exit(0); } else // parent wait if fg set { if (fg) { fgpid = pid; //set global fgpid to current pid strcpy(fgcommands, commands); fgstatus = _RUNNING; // start fgstatus to _RUNNING // Unblock SIGCHLD before busy loop sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); while (fgstatus) { sleep(1); } } else // bg { char* ampersand = " &"; strcat(commands, ampersand); int jobnumber = addjob(pid, _RUNNING, commands, _JOBLIST); if (jobnumber == 0) PrintPError("Error in adding job"); // Unblock SIGCHLD after adding to job list sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); } } } else // fork errors { PrintPError("Error in fork"); } free(commands); } /* Exec */
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"); } } } }
/* * ResolveExternalCmd * * arguments: * commandT *cmd: the command to be run * * returns: bool: whether the given command exists * * Determines whether the command to be run actually exists. */ static bool ResolveExternalCmd(commandT* cmd, char* path) { //printf("Command: %s\n", cmd->name); //Check to see if in home directory: if(*(cmd->argv[0])=='.'){ char* cwd = getCurrentWorkingDir(); //char* cwd; //getCurrentWorkingDir(cwd); sprintf(path,"%s/%s",cwd,cmd->name); free(cwd); return TRUE; } char** memLocs = getPath(); char dest[500]; int i=0; struct stat buf; /*If already absolute path*/ if(stat(cmd->name,&buf)==0){ /*Set path = to entered absolute path*/ strcpy(path,cmd->name); freePath(memLocs); return TRUE; } while(memLocs[i]!=NULL){ //Concatanate Paths with cmd->name: int size = (snprintf( dest, 499,"%s/%s",memLocs[i],cmd->name)+1)*sizeof(char); char* exeName = (char*)malloc(size); sprintf(exeName,"%s/%s",memLocs[i],cmd->name); //printf("%s/%s\n", memLocs[i], cmd->name); //Check to see if exists and executable: if(stat(exeName,&buf)==0){ if(S_ISREG(buf.st_mode) && buf.st_mode & 0111){ strncpy(path,exeName,size); freePath(memLocs); free(exeName); return TRUE; } char* error = malloc(PATHSIZE * sizeof(char*)); strcpy(error, "line 1: "); //since script reading is not in the functionality, it will be an error on line 1 strcat(error, cmd->argv[0]); PrintPError(error); free(error); freePath(memLocs); free(exeName); return FALSE; } i++; free(exeName); } char* error = malloc(PATHSIZE * sizeof(char*)); strcpy(error, "line 1: "); //since script reading is not in the functionality, it will be an error on line 1 strcat(error, cmd->argv[0]); PrintPError(error); free(error); freePath(memLocs); return FALSE; } /* ResolveExternalCmd */