int built_cmd (CMD *cmd) { int status = SUCCESS; if (!cmd) return status; if(cmd->fromType != NONE) { //setup input redirection int red_err = set_red_in(cmd); if(red_err != SUCCESS) { perror("RED_IN: "); exit(red_err); } } if(cmd->toType != NONE) { //setup output redirection int red_err = set_red_out(cmd); if (red_err != SUCCESS) { perror("RED_OUT: "); exit(red_err); } } if (strcmp(cmd->argv[0], "dirs") == 0) status = exec_dirs(); else if (strcmp(cmd->argv[0], "cd") == 0) status = exec_cd(cmd); else if (strcmp(cmd->argv[0], "wait") == 0) status = exec_wait(); return status; }
/* * Executes the program specified. * argv must be null-terminated. * * istream, ostream, and errstream give file descriptors for input, output, and * error. If specified, the child will use these instead of the standard ones. * * Returns: * | 0 if successful * | -1 if program errored (errno maintaned) * | -2 if child process was unable to complete execution * | -3 if fork failed * | * | -12 if input redirection failed * | -14 if output redirection failed * | -16 if error redirection failed * | * | -101 if argv was not null-terminated */ int exec_program(char *program, int argc, char **argv, int istream, int ostream, int errstream, int* to_close) { pid_t child_pid; child_pid = fork(); if(argv[argc] != 0) { // check null termination return -101; } if(strcmp(program, "cd") == 0 || strcmp(program, "chdir") == 0) { exec_cd(argc, argv, istream, ostream, errstream); } if(strcmp(program, "exit") == 0) { exit(0); } if(child_pid >= 0) { if(child_pid == 0) { // child if(to_close[1] >= 0) { close(to_close[1]); } //redirection if(istream != STDIN_FILENO) { int err = dup2(istream, 0); if(err < 0) { exit(-11); } } if(ostream != STDOUT_FILENO) { int err = dup2(ostream, 1); if(err < 0) { exit(-12); } } if(errstream != STDERR_FILENO) { int err = dup2(errstream, 2); if(err < 0) { exit(-13); } } // execution int success = execvp(program, argv); if(success == -1) { exit(errno); } else { exit(0); } } else { // parent if(istream != STDIN_FILENO) { close(istream); } if(ostream != STDOUT_FILENO) { close(ostream); } if(errstream != STDERR_FILENO) { close(errstream); } } } else { return -3; } }
/*parse command to linked list and send to exec function*/ void parse_command(){ int EXIT; int i=0,j,d; int test = 0; int length = strlen(buffer); int count = 1; int start = 0; int temp = 0; int currarg = 0; struct Node* head = malloc(sizeof(struct Node)); memset(head->args,0,sizeof(int) * 50); head->next = NULL; struct Node* ptr = head; for(i = 0; i < length; i++){ char c = buffer[i]; if(currarg >= 50){ fprintf(stderr,"Too many arguements\n"); test = 2; break; } if(!temp){ if(c == '|'){ count++; currarg = 0; ptr->next = malloc(sizeof(struct Node)); ptr = ptr->next; memset(ptr->args,0,sizeof(int) * 50); ptr->next = NULL; }else if(c == '\''){ temp = 1; start = i; }else if(c == '\"'){ temp = 2; start = i; }else if(c != ' ' && c!= '\t'){ temp = 3; start = i; } }else if((temp == 1 && c == '\'') || (temp == 2 && c == '\"')){ temp = 0; ptr->args[currarg] = malloc(sizeof(char) * (i - start + 2)); memcpy(ptr->args[currarg],buffer + sizeof(char) * (start + 1), sizeof(char) * ((i - 1) - start)); ptr->args[currarg][(i - 1) - start] = '\0'; currarg++; }else if(temp == 3 && (c == ' ' || i == length - 1)){ temp = 0; ptr->args[currarg] = malloc(sizeof(char) * (i - start + 2)); memcpy(ptr->args[currarg],buffer + sizeof(char) * start, sizeof(char) * (i - start)); ptr->args[currarg][i - start] = '\0'; currarg++; }else if(temp == 3 && c == '|'){ temp = 0; ptr->args[currarg] = malloc(sizeof(char) * (i - start + 2)); memcpy(ptr->args[currarg],buffer + sizeof(char) * start, sizeof(char) * (i - start)); ptr->args[currarg][i - start] = '\0'; count++; currarg = 0; ptr->next = malloc(sizeof(struct Node)); ptr = ptr->next; memset(ptr->args,0,sizeof(int) * 50); ptr->next = NULL; }else if(c == '\'' || c == '\"'){ fprintf(stderr,"error: quote mismatch\n"); test = 1; break; } } /*send to cd function*/ if(!strcmp(head->args[0], "cd")){ exec_cd(2, head->args); freeList(head); return; } /*send to exit function*/ if(!strcmp(head->args[0], "exit")){ exec_exit(2, head->args); freeList(head); return; } if(!test && (temp == 1 || temp == 2)){ fprintf(stderr,"error: quote mismatch\n"); test = 1; } if(head->args[0] == NULL){ test = 1; } if(!test){ exec_command(head, -1); int status; int pid; while((pid = wait(&status)) != -1) printf("process %i exits with %i\n",pid,status); } freeList(head); }
// Invokes a command, assuming it has no pipes. int invoke(char *input, int will_fork) { int stdin_copy = dup(0); int stdout_copy = dup(1); // First, we want to determine whether we need any redirects. char **files = tokenize_redirects(input); unsigned int i; char *infile = NULL; char *outfile = NULL; int status; // Clean up the array contents. char **tokens = tokenize(files[0]); char **infiles; if (files[1]) { infiles = tokenize(files[1]); infile = infiles[0]; } char **outfiles; if (files[2]) { outfiles = tokenize(files[2]); outfile = outfiles[0]; } if (infile) { int in_fd = open(infile, O_RDONLY); if (in_fd == -1) { fprintf(stderr, "open failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } dup2(in_fd, STDIN_FILENO); status = close(in_fd); if (status == -1) { fprintf(stderr, "close failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } } if (outfile) { int out_fd = open(outfile, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); if (out_fd == -1) { fprintf(stderr, "open failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } dup2(out_fd, STDOUT_FILENO); status = close(out_fd); if (status == -1) { fprintf(stderr, "close failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } } // Handle built in commands. if (!tokens[0]) return 0; if (strcmp(tokens[0], "cd") == 0 || strcmp(tokens[0], "chdir") == 0) { exec_cd(tokens); } else if (strcmp(tokens[0], "history") == 0) { exec_hist(tokens); } else if (strcmp(tokens[0], "exit") == 0) { exit(EXIT_SUCCESS); } else { if (will_fork) { // Based on how invoke is called, fork. pid_t pid = fork(); if (pid == -1) { fprintf(stderr, "fork failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } else if (pid == 0) { if (execvp(tokens[0], tokens) == -1) { fprintf(stderr, "execvp failed: %s\n", strerror(errno)); } } else { wait(&status); } } else { if (execvp(tokens[0], tokens) == -1) { fprintf(stderr, "execvp failed: %s\n", strerror(errno)); } } } dup2(stdin_copy, STDIN_FILENO); dup2(stdout_copy, STDOUT_FILENO); // Memory management. for (i = 0; tokens[i] != NULL; i++) { free(tokens[i]); } free(tokens); if (files[1]) { for (i = 0; infiles[i] != NULL; i++) { free(infiles[i]); } free(infiles); } if (files[2]) { for (i = 0; outfiles[i] != NULL; i++) { free(outfiles[i]); } free(outfiles); } for (i = 0; i < 3; i++) { if (files[i]) { free(files[i]); } } free(files); return 0; }