//this function does what's needed for each built-in command. Note: these commands cannot be //run in the background. Returns 1 if a built-in command is detected, 0 if not int builtInCmd(char *argList[], struct hist *histList, int count) { int cdCheck; int isBuiltIn = 1; //builtin exit command if (strcmp(argList[0], "exit") == 0) { printf("Exiting shell...\n\n"); exit(0); //builtin cd (change directory) command, implemented with chdir() system call } else if (strcmp(argList[0], "cd") == 0) { if ((cdCheck = chdir(argList[1]) == -1)) { printf("chdir() failure... now exiting shell"); _exit(EXIT_FAILURE); } //builtin command to display history } else if (strcmp(argList[0], "history") == 0) { printHistory(&histList[0], count); //builtin command to display currently running jobs } else if (strcmp(argList[0], "jobs") == 0) { updateJobs(); printJobs(); //builtin command to bring a background job to the foreground } else if (strcmp(argList[0], "fg") == 0) { if (argList[1] == NULL) printf("Invalid command: must give a Process ID number with the fg command.\n"); if (bringToForeground(argList) == 0) printf("The process with that PID is not currently running.\n"); } else { isBuiltIn = 0; } return isBuiltIn; }
static void RunBuiltInCmd(commandT* cmd) { if(strcmp(cmd->argv[0], "cd") == 0) { // FILL IN } else if(strcmp(cmd->argv[0], "bg") == 0) { if (cmd->argc == 2) { bg(atoi(cmd->argv[1])); } else { printf("Invalid number of arguments for bg\n"); fflush(stdout); } } else if(strcmp(cmd->argv[0], "fg") == 0) { if (cmd->argc == 2) { fg(atoi(cmd->argv[1])); } else { printf("Invalid number of arguments for fg\n"); fflush(stdout); } } else if(strcmp(cmd->argv[0], "jobs") == 0) { printJobs(); } }
int builtInCommand(char *argv) { if (strcmp(argv, "exit") == 0) { exit(EXIT_SUCCESS); } else if (strncmp(argv, "cd", 2) == 0) { return cd(argv); } else if (strcmp(argv, "jobs") == 0) { printJobs(); return 1; } else if (strncmp(argv, "bg", 2) == 0) { bg(argv); return 1; } else if (strncmp(argv, "fg", 2) == 0) { fg(argv); return 1; } return 0; }
int main(int argc, char *argv[]){ char *line; pipeline pl; int run; //flags int redo = 0; int skip = 0; int isResume = 0; char *promptstr; char* buffer; numExits = 0; jobIndex = 0; histIndex = 0; back = 0; script = 0; FILE* in; /* check for the right number of arguments */ //if ( argc > 2 ) { // printusage(argv[0]); // exit(-1); //} if (argc >= 2) { DIR* dirp; struct dirent *dp; int isFound = 0; if ((dirp = opendir(".")) == NULL) { perror("couldn't open path"); return 0; } //put files into array and sort their names while ((dp = readdir(dirp)) != NULL) { if (strcmp(dp->d_name, argv[1]) == 0) { isFound = 1; } } if (isFound == 0) { printf("%s: Command not found\n", argv[1]); } else { in = fopen(argv[1], "r"); buffer = (char*)malloc(sizeof(in)); script = 1; } } //struct termios saved_term_mode; struct sigaction action; action.sa_handler = killHandle; /* set tick to be the handler function */ sigemptyset(&action.sa_mask); /* clear out masked functions */ action.sa_flags = 0; /* no special handling */ struct sigaction action2; action2.sa_handler = susHandle; /* set tick to be the handler function */ sigemptyset(&action2.sa_mask); /* clear out masked functions */ action2.sa_flags = 0; /* no special handling */ /* * Use the sigaction function to associate the signal action with SIGALRM. */ if (sigaction(SIGINT, &action, NULL) < 0 ) { fprintf(stderr, "SIGINT\n"); exit(-1); } if(sigaction(SIGTSTP, &action2, NULL) < 0) { fprintf(stderr, "SIGTSTP\n"); exit(-1); } //saved_term_mode = set_raw_term_mode(); initHistory(); initJobs(); //strcpy(jobs[1], "hey"); /* set prompt */ promptstr = PROMPT; run = TRUE; if (script == 0) prompt(promptstr); while ( run ) { /// if reexecute was not called if (redo == 0) { if (script == 0) { if ( NULL == (line = readLongString(stdin)) ) { if ( feof(stdin) ) run = FALSE; } } else { fgets(line, sizeof(in), in); if (line[0] == '%') { line++; isResume = 1; } } } else { //printf("histInd: %d\n", histIndex); ///if reexecute was called, ///find the correct place in the history ///list to extract the reexecuted command int temp = histIndex; temp--; int ind = 0; while (ind != reNumber) { temp--; ind++; } line = history[temp]; printf("%s\n", line); } if (line == NULL) { if (feof(stdin)) run = FALSE; } else { if (line[0] == '%') { line++; isResume = 1; } /* We got a line, send it off to the pipeline cracker and * launch it */ //if (redo == 0) //{ pl = crack_pipeline(line); //} redo = 0; /* * Show that it worked. This is where you're going to do * something radically different: rather than printing the * pipeline, you're going to execute it. */ if ( pl != NULL && strlen(pl->cline) > 0) { /* if (pl->cline[0] == '%') { int i; isResume = 1; pl->stage[0].argv[0][0] = ' '; for (i = 0; i < strlen(pl->cline)-1; i++) { pl->stage[0].argv[0][i] = pl->stage[0].argv[0][i+1]; } pl->stage[0].argv[0][strlen(pl->cline)-1] = '\0'; } */ //print_pipeline(stdout,pl); /* print it. */ addHistory(pl->cline); ///add to the history what was typed into the command line if (strcmp(pl->stage[0].argv[0], "history") == 0) { ///print the history if possible if (pl->stage[0].argc > 1) { printf("Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) printHistory(); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "jobs") == 0) { ///print the suspended jobs if possible if (pl->stage[0].argc > 1) { printf("Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) printJobs(); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "exit") == 0) { ///exit vssh if possible if (pl->stage[0].argc > 1) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits++; if (skip == 0) exitCmd(); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "bg") == 0) { ///background the most recently suspended job if possible if (pl->stage[0].argc > 1) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) bg(jobs[jobIndex-1]); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "fg") == 0) { ///foreground the most recently backgrounded job if possible if (pl->stage[0].argc > 1) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) fg(jobs[jobIndex-1]); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "cd") == 0) { ///change the directory of vssh if possible if (pl->stage[0].argc > 2) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) cd(pl->stage[0].argv[1]); skip = 0; } else if (isResume == 1) { ///foreground the specified job if possible if (pl->stage[0].argc > 1) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) { //pl->stage[0].argv[0]++; int i; int killFlag = 0; for (i = 0; i < strlen(pl->stage[0].argv[0]); i++) { if (!isdigit(pl->stage[0].argv[0][i])) { ///if the supplied job number is not a number ///then print error killFlag = 1; fprintf(stderr, "%s: No such job.\n", pl->stage[0].argv[0]); } } if (killFlag == 0) { if (atoi(pl->stage[0].argv[0]) <= 0 || atoi(pl->stage[0].argv[0]) > jobIndex) ///if the supplied job number is not a valid job index ///then print error fprintf(stderr, "%s: No such job.\n", pl->stage[0].argv[0]); else resume(jobs[atoi(pl->stage[0].argv[0])-1]->id, atoi(pl->stage[0].argv[0])-1); } } skip = 0; } else if (strcmp(pl->stage[0].argv[0], "!") == 0) { ///reexecute the specified history command if possible if (pl->stage[0].argc > 2 || strlen(pl->stage[0].argv[1]) > 3) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } ///if the number supplied is not a valid history index ///then print error if (pl->stage[0].argv[1][0] == '0' && skip == 0) { fprintf(stderr, "%s: Event not found\n", pl->stage[0].argv[1]); skip = 1; } if (strlen(history[atoi(pl->stage[0].argv[1])]) <= 0 && skip == 0) { fprintf(stderr, "%s: Event not found\n", pl->stage[0].argv[1]); skip = 1; } int i; for (i = 0; i < strlen(pl->stage[0].argv[1]); i++) { if (!isdigit(pl->stage[0].argv[1][i]) && skip == 0) { ///if the number supplied is not a number ///then print error fprintf(stderr, "%s: Event not found\n", pl->stage[0].argv[1]); skip = 1; } } numExits = 0; if (skip == 0) { redo = 1; reNumber = atoi(pl->stage[0].argv[1]); //printf("renum: %d\n", reNumber); //pl = crack_pipeline(history[atoi(pl->stage[0].argv[1])]); //printf("%s\n", pl->cline); //lineno++; //continue; } skip = 0; } else if (strcmp(pl->stage[0].argv[0], "kill") == 0) { ///kill the specified job if possible if (pl->stage[0].argc > 2) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) { int i; int killFlag = 0; for (i = 0; i < strlen(pl->stage[0].argv[1]); i++) { ///if the supplied job number is not a number ///then print error if (!isdigit(pl->stage[0].argv[1][i])) { killFlag = 1; fprintf(stderr, "%s: No such job.\n", pl->stage[0].argv[1]); } } if (killFlag == 0) { if (atoi(pl->stage[0].argv[1]) <= 0 || atoi(pl->stage[0].argv[1]) > jobIndex) ///if the supplied job number is not a valid job index ///then print error fprintf(stderr, "%s: No such job.\n", pl->stage[0].argv[1]); else killProcess(atoi(pl->stage[0].argv[1])-1, jobs[atoi(pl->stage[0].argv[1])-1]->id); } } skip = 0; } else { ///pipe/redirect as necessary numExits = 0; //int i; //for (i = 0; i < pl->length; i++) //{ //else //{ //handle backgrounding "&" //find the & int j; int andFound = 0; int pipeFound = 0; for (j = 1; j < strlen(pl->cline); j++) { if (pl->cline[j] == '|') { //fprintf(stderr, "Pipelines cannot be backgrounded\n"); pipeFound = 1; } else if (pl->cline[j] == '&') { //error if & is not the last arg, exec nothing if (pipeFound == 1) { fprintf(stderr, "Pipelines cannot be backgrounded\n"); } else if (j != strlen(pl->cline) - 1) { andFound = 1; fprintf(stderr, "Junk after '&'.\n"); } else if (pl->cline[j-1] == ' ') { andFound = 1; pl->cline[j] = '\0'; //backExec(pl->stage[0].argv[0], pl->stage[0].argv, pl->cline); back = 1; } } } if (pl->length >= 2) { ///pipe if the pipline has 2 or more stages pipeCmd(pl); } else if (pl->stage[0].outname != NULL && pl->stage[0].inname != NULL) { redirectBoth(pl->stage[0].argv, pl->stage[0].inname, pl->stage[0].outname); } else if (pl->stage[0].outname != NULL) { ///otherwise redirect output if there is an outfile redirectOutput(pl->stage[0].argv, pl->stage[0].outname, pl->cline); } else if (pl->stage[0].inname != NULL) { ///otherwise redirect input if there is an infile redirectInput(pl->stage[0].argv, pl->stage[0].inname, pl->cline); } else if (andFound == 0) { //execute if not a built-in command execute(pl->stage[0].argv[0], pl->stage[0].argv, pl->cline); } back = 0; //} //} } } free_pipeline(pl); fflush(stdout); /* also frees line */ lineno++; /* readLongString trims newlines, so increment it manually */ } if (run ) { if (script == 0) /* assuming we still want to run */ prompt(promptstr); } } return 0; }
int checkBuiltInCommands() { if (strcmp("exit", commandArgv[0]) == 0) { puts("\nExiting. Thanks for using myShell!\n"); exit(EXIT_SUCCESS); } if (strcmp("cd", commandArgv[0]) == 0) { //add_command_to_history(commandArgv[0]); changeDirectory(); return 1; } /* if (strcmp("in", commandArgv[0]) == 0) { launchJob(commandArgv + 2, *(commandArgv + 1), STDIN, FOREGROUND); return 1; } if (strcmp("out", commandArgv[0]) == 0) { launchJob(commandArgv + 2, *(commandArgv + 1), STDOUT, FOREGROUND); return 1; }*/ if (strcmp("bg", commandArgv[0]) == 0) { //add_command_to_history(commandArgv[0]); if (commandArgv[1] == NULL) return 0; /*if (strcmp("in", commandArgv[1]) == 0) launchJob(commandArgv + 3, *(commandArgv + 2), STDIN, BACKGROUND); else if (strcmp("out", commandArgv[1]) == 0) launchJob(commandArgv + 3, *(commandArgv + 2), STDOUT, BACKGROUND); else launchJob(commandArgv + 1, "STANDARD", 0, BACKGROUND);*/ int jobId = (int) atoi(commandArgv[1]); t_job* job = getJob(jobId, BY_JOB_ID); if(job == NULL) return 0; if(job->status == SUSPENDED){ fprintf(stdout, "converting program from suspended to background wait status: "); puts(job->name); putJobBackground(job, TRUE); //launchJob(job->name, "STANDARD", 0, BACKGROUND); } else{ putJobBackground(job, FALSE); fprintf(stdout, "program already in a wait status."); } return 1; } if (strcmp("&", commandArgv[commandArgc-1]) == 0){ // commandArgv[1] for bg after file //printf("%s", commandArgv[0]); if (strcmp("&", commandArgv[0]) == 0) // commandArgv[0] for bg after file return 0; else{ //puts(commandArgv); //printf("commandArgv: %p\n", commandArgv); launchJob(commandArgv, "STANDARD", 0, BACKGROUND); // ommandArgv for bg after file } return 1; } else{ //printf("%s", commandArgv[0]); } if (strcmp("fg", commandArgv[0]) == 0) { //add_command_to_history(commandArgv[0]); if (commandArgv[1] == NULL) return 0; int jobId = (int) atoi(commandArgv[1]); t_job* job = getJob(jobId, BY_JOB_ID); if (job == NULL) return 0; if (job->status == SUSPENDED || job->status == WAITING_INPUT){ fprintf(stdout, "bringing program from background to run: "); puts(job->name); putJobForeground(job, TRUE); } else // status = BACKGROUND putJobForeground(job, FALSE); return 1; } if (strcmp("jobs", commandArgv[0]) == 0) { //add_command_to_history(commandArgv[0]); printJobs(); return 1; } if (strcmp("kill", commandArgv[0]) == 0) { //add_command_to_history(commandArgv[0]); if (commandArgv[1] == NULL) return 0; char *nextCharPtr; char testString[10]; strcpy(testString, commandArgv[1]); char *test = testString; if(strncmp("%", test, 1) == 0) { nextCharPtr = strtok(testString, "%"); killJob((atoi(nextCharPtr))); return 1; } else{ killJobCredit((atoi(commandArgv[1]))); return 1; } } /*if(strcmp("!1", commandArgv[0]) == 0){ char *cP; int number; cP = strtok(commandArgv[0], "!"); number = atoi(cP)-1; char historyPoint[60]; char *hisString; char *newCommand[10]; int i; for(i = 0; i < 60; i++){ historyPoint[i] = (char)history[number][i]; } hisString = strtok(historyPoint, ""); printf("%s\n", hisString); //historyPoint = history[number]; //printf("%s\n", historyPoint); newCommand[0] = hisString; //printf("commandArgv: %s\n", commandArgv[0]); commandArgv[0] = newCommand[0]; //printf("new commandArgv: %s\n", commandArgv[0]); //printf("%s\n", newCommand[0]); //launchJob(newCommand[0], "STANDARD", 0, FOREGROUND); //executeCommand(commandArgv[0], "STANDARD", 0, FOREGROUND); return 1; }*/ if(strcmp("history", commandArgv[0]) == 0) { int index; int column; int count = 1; printf("Command History List\n"); printf("%d: ", count); for(index = 0; index < 10; index++){ for(column = 0; column < 55; column++){ fprintf(stdout, "%c", history[index][column]); } count++; //printf("%d: ", count); if(count <= 10){ printf("\n"); printf("%d: ", count); } if(count == 11) printf("\n"); //count++; } return 1; } if(strcmp("help", commandArgv[0]) == 0) { printf("Help Menu\n"); printf("The functionality of this shell is as follows:\n\n"); printf("The execution of simple normal shell operations such as cat, more, echo, any user-defined program, etc. will\n"); printf("operate exactly as they would in the bash shell.\n"); printf("The built-in commands ls, cd, ps and pwd will operate just as they would in the bash shell as well.\n"); printf("To start a program in the background simply append the & symbol such as, ./program &\n"); printf("The command jobs can be used to list the processes that are currently running in the background of your shell.\n"); printf("If a program has been suspended, such as the user entering CTRL-Z, you can background the job to wait status using\n"); printf("the command bg <job number> e.g. bg 1\n"); printf("If a job is in the background, either in wait-status or suspended, it can be brought to the foreground by using the\n"); printf("command fg <job number> e.g. fg 1\n"); printf("A job can be killed using the command kill %<job number> such as kill %1 or using the pid number, kill <pid number>\n"); printf("You can obtain the pid number of a job from the jobs list or the ps command.\n"); printf("Simple input/output redirection is accomplished as follows:\n"); printf("./a.out < input -- would run program a.out with input from file input and would write all output to stdout\n"); printf("./a.out > output -- would run program a.out with output of program sent to the created file output\n"); printf("./a.out < input > output -- would run program a.out with input from file input and would write output to the created file output.\n"); printf("./a.out >> output -- would run program a.out with output of program appended to the end of the previously created file output.\n"); printf("./a.out < input >> output -- would run program a.out with input from file input and append output to the end of the previously\n"); printf("created file output.\n"); printf("Simple pipe functionality has also been implemented in this shell. An example is as follows:\n"); printf("who | wc -- would run command who and pipe output to the word count process\n"); printf("To see a list of previously entered commands type history at the shell prompt, only ten commands are held in history per shell execution.\n"); printf("To execute a previous command listed in history type !<command number> e.g. !1 at the shell prompt."); printf("To exit the shell program type exit at the shell prompt.\n\n"); printf("End of Help Menu\n"); return 1; } //int i; ////for( i=0;i<=commandArgc;i++) //{ //char *str; //strcpy(str,commandArgv); if( commandArgc == 3 ) { if(strcmp("|", commandArgv[1]) == 0 ) { pipelining(2); return 1; } else if(strcmp("<", commandArgv[commandArgc-2]) == 0){ int in; int i = 0; i = fork(); if(i == 0){ in = open(commandArgv[2], O_RDONLY); dup2(in, 0); close(in); executeCommand(commandArgv, "STANDARD", 0, FOREGROUND); //puts("test statement 1"); dup2(0, 0); //printf("test statement 2"); }else{ waitpid(getpid(), NULL, 0); close(in); } return 1; } else if(strcmp(">", commandArgv[commandArgc-2]) == 0){ int out; int i = 0; i = fork(); if(i == 0){ out = open(commandArgv[2], O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); dup2(out, 1); close(out); executeCommand(commandArgv, "STANDARD", 0, FOREGROUND); //printf("test statement 3"); dup2(1, 1); //printf("test statement 4"); }else{ waitpid(getpid(), NULL, 0); close(out); } return 1; } else if(strcmp(">>", commandArgv[commandArgc-2]) == 0){ int out; int i = 0; int offset; i = fork(); if(i == 0){ out = open(commandArgv[2], O_WRONLY | O_APPEND); offset = lseek(out, 1, SEEK_END); dup2(out, 1); close(out); executeCommandAppend(commandArgv, "STANDARD", 0, FOREGROUND); dup2(1, 1); }else{ waitpid(getpid(), NULL, 0); close(out); } return 1; } } if( commandArgc > 3 ) { if(strcmp(">", commandArgv[commandArgc-2]) == 0){ int in; int out; int i = 0; i = fork(); if(i == 0){ in = open(commandArgv[2], O_RDONLY); out = open(commandArgv[4], O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); dup2(in, 0); dup2(out, 1); close(in); close(out); executeCommand(commandArgv, "STANDARD", 0, FOREGROUND); dup2(0, 0); dup2(1, 1); }else{ waitpid(getpid(), NULL, 0); close(in); close(out); } return 1; } else if(strcmp("|", commandArgv[commandArgc-2]) == 0 ) { //puts("works"); //printf("%d",commandArgc); pipelining(commandArgc-1); return 1; } else if(strcmp(">>", commandArgv[commandArgc-2]) == 0){ int in; int out; int offset; int i = 0; i = fork(); if(i == 0){ in = open(commandArgv[2], O_RDONLY); out = open(commandArgv[4], O_WRONLY | O_APPEND); offset = lseek(out, 1, SEEK_END); dup2(in, 0); dup2(out, 1); close(in); close(out); executeCommandAppend(commandArgv, "STANDARD", 0, FOREGROUND); dup2(0, 0); dup2(1, 1); }else{ waitpid(getpid(), NULL, 0); close(in); close(out); } return 1; } } //break; //} return 0; }
void printSchedule(std::vector<Job*> currentSchedule, char *textMessage, double currentScore){ char label[100]; printed++; snprintf(label, sizeof(label), "%s, score = %2.2lf", textMessage, currentScore); printJobs(currentSchedule, label); }
/** * runCommand: * @command: string holding the current command * @cmdCount: variable holding the current number of commands * * The function analyzes the command, categorizes as built-in, user-defined and * system. Performs the necessary task of creating child processes and executing * he command. Handles all the piping and redirection stuff. */ void runCommand(char *command, unsigned int *cmdCount) { pid_t pid; int status; size_t i, j; int procLoc = PROC_LOC_FG; int jobID = 0; char *commandCopy = strdup(command); char **cmd = parseCommand(command, " "); unsigned int cmdLength = stringListLength(cmd); if (!cmdLength) return; /* Is the process to be run in background? */ for (i = 0; i < cmdLength; i++) { if (STREQ(cmd[i], "&")) { cmd[i] = NULL; procLoc = PROC_LOC_BG; } } /* Is it a built-in command? */ if (STREQ(cmd[0], "cd")) { if (chdir(cmdLength > 1 && cmd[1] != NULL ? cmd[1] : HOME) < 0) perror("chdir() error"); } /* Is it a user-defined command? */ else if (STREQ(cmd[0], "pinfo")) { if (cmdLength > 1) printInfo(atoi(cmd[1])); else printInfo(-1); } else if (STREQ(cmd[0], "jobs")) { printJobs(); } else if (STREQ(cmd[0], "quit") || STREQ(cmd[0], "exit")) { killBGProcs(); _exit(0); } else if (STREQ(cmd[0], "kjob")) { if (cmdLength != 3) printf("Correct syntax is: kjob <jobNumber> <signalNumber>\n"); else killProc(atoi(cmd[1]), atoi(cmd[2])); } else if (STREQ(cmd[0], "overkill")) { killBGProcs(); } else if (STREQ(cmd[0], "fg")) { if (cmdLength != 2) printf("Correct syntax is: fg <jobNumber>\n"); else wakeUpBG(atoi(cmd[1])); } else if (cmd[0][0] == 0x0C) { printf("\033[2J\033[H"); } else { /* Is it a system command? */ if ((pid = fork()) < 0) { printf("ERROR: forking child process failed\n"); _exit(1); } else if (pid == 0) { char **cmdChild = NULL; int redirection[REDIRECTION_MAX]; int redirectCount = 0; unsigned int nCmds = 0; pid_t cpid; int fd[2]; int tmp_fd; if (procLoc == PROC_LOC_BG) setpgid(0, 0); for (i = 0; i < strlen(commandCopy); i++) { switch(commandCopy[i]) { case '>': redirection[redirectCount++] = '>'; break; case '|': redirection[redirectCount++] = '|'; break; } } cmdChild = parseCommand(commandCopy, "|>"); nCmds = stringListLength(cmdChild); if (nCmds > 2) { for (i = 0; i < nCmds; i++) { if (pipe(fd) < 0) perror("pipe error"); if ((cpid = fork()) < 0) { perror("fork error"); } else if (cpid == 0) { close(fd[0]); char **tmpCmd = parseCommand(cmdChild[i], " "); int tmpLen = stringListLength(tmpCmd); for (j = 0; j < tmpLen; j++) { if (STREQ(tmpCmd[j], "<")) { tmpCmd[j] = tmpCmd[j + 1]; tmpCmd[j + 1] = NULL; break; } else if (STREQ(tmpCmd[j], "&")) tmpCmd[j] = NULL; } if (redirection[i] == '>') { char **path = parseCommand(cmdChild[i + 1], " "); tmp_fd = open(path[0], O_CREAT | O_WRONLY | O_TRUNC, 0644); dup2(tmp_fd, STDOUT_FILENO); close(tmp_fd); } else if (i != (nCmds - 1)) dup2(fd[1], STDOUT_FILENO); if ((redirection[i - 1] != '>') && (execvp(*tmpCmd, tmpCmd) < 0)){ printf("ERROR: %s: command not found\n", tmpCmd[0]); _exit(1); } close(fd[1]); _exit(0); } else { close(fd[1]); if (waitpid(cpid, NULL, 0) < 0) perror("waitpid error"); if (i != (nCmds - 1)) dup2(fd[0], STDIN_FILENO); close(fd[0]); } } } else if (execvp(*cmd, cmd) < 0) { printf("ERROR: %s: command not found\n", cmd[0]); _exit(1); } _exit(0); } else{ CURRPID = pid; jobID = JOBID++; PROCINFO = realloc(PROCINFO, sizeof(procInfo)*(jobID + 1)); PROCINFO[jobID].cmd = commandCopy; PROCINFO[jobID].pid = pid; PROCINFO[jobID].location = procLoc; if(procLoc == PROC_LOC_FG) { waitpid(-1, &status, WUNTRACED); } } } stringListFree(cmd); cleanZombies(); }
int main(int argc, char *argv[], char *envp[]) { command_t cmd; //< Command holder argument start(); puts("Welcome to Quash!"); puts("Type \"exit\" or \"quit\" to quit"); // Main execution loop /*while (is_running() && get_command(&cmd, stdin)) { // NOTE: I would not recommend keeping anything inside the body of // this while loop. It is just an example. // The commands should be parsed, then executed. if (!strcmp(cmd.cmdstr, "exit")) terminate(); // Exit Quash else puts(cmd.cmdstr); // Echo the input string }*/ pid = (int *)malloc(30 * sizeof(int)); commandArray = (char**)malloc(32*sizeof(char*)); z = 0; char* inputString; while(1){ printf("$ "); get_command(&cmd, stdin); inputString = cmd.cmdstr; if(strcmp(inputString, "exit") == 0 || strcmp(inputString, "quit") == 0){ printf("Goodbye.\n"); return EXIT_SUCCESS; }else if(strncmp(inputString, "set", 3) == 0){ char setter[1024]; strcpy(setter, inputString); setPathOrHome(inputString); }else if(strncmp(inputString, "echo", 4) == 0){ printEcho(inputString); }else if(strcmp(inputString, "pwd") == 0){ call_getcwd(); }else if(strncmp(inputString, "cd", 2) == 0){ char* token = strtok(inputString, " "); token = strtok(NULL, " "); if(token == NULL){ call_chdir(getenv("HOME")); }else{ call_chdir(token); } }else if(strcmp(inputString, "jobs") == 0){ printJobs(); }else{ execute(inputString, envp); } //free(inputString); } return EXIT_SUCCESS; }