void doExec (char *p, int oargc, char **oargv, int first) { char *argv[ARGVMAX]; int argc; closeAllPipes(); parseArgs (p, &argc, argv); if (first) { appendArgs (argc, argv, oargc, oargv); } argc = 0; if (execvp (argv[0], argv) < 0) quit ("exec failed"); }
int main() { //Set up to ignore SIGINT and SIGQUIT struct sigaction newact, oldact; newact.sa_handler = SIG_IGN; sigaction(SIGINT, &newact, &oldact); sigaction(SIGQUIT, &newact, &oldact); while(1) { char* prompt = setPromptString(); printf("%s", prompt); char* input_string = getInputString(); //Initialize array to hold commands size_t commands_alloc_size = COMMANDS_INITIAL_SIZE; int num_commands = 0; command* commands = malloc(sizeof(command) * commands_alloc_size); fillCommandArray(input_string, &commands, &num_commands, &commands_alloc_size); bool wasShellCommand = handleShellCommand(commands[0]); if (wasShellCommand == false) { int** fds = createPipes(num_commands); for (int i = 0; i < num_commands; ++i) { pid_t fork_pid = fork(); if (fork_pid == -1) { perror("Fork failed"); exit(1); } //Child process else if (fork_pid == 0) { sigaction(SIGINT, &oldact, NULL); sigaction(SIGQUIT, &oldact, NULL); executeCommand(fds, num_commands, commands[i], i); } } //Clean up the shell process closeAllPipes(fds, num_commands); waitForAllChildProcesses(num_commands); freeCommandArray(commands, num_commands); } } return 0; }
/* Execute command while taking pipes into account Input: fds: an array to 2-int array file descriptors num_commands: the number of commands index: the current index of the command in the pipe chain */ void executeCommand(int** fds, int num_commands, command cmd, int index) { //close stdin, duplicate previous command's pipe input to stdin //except when this is first command if (index != 0) { int prev_cmd_index = index - 1; if (dup2(fds[prev_cmd_index][0], 0) == -1) { perror("dup2(fds[prev_cmd_index][0], 0) failed"); exit(1); } } //Handle input redirection else if (index == 0 && cmd.input_redirect_filename != NULL) { int input_fd = open(cmd.input_redirect_filename, O_RDONLY); if (input_fd == -1) { perror("open input file failed"); exit(1); } if (dup2(input_fd, 0) == -1) { perror("dup2(input_fd, 0) failed"); exit(1); } } //close stdout, duplicate current pipe output to stdout //except when this is the last command if (index != (num_commands - 1)) { if (dup2(fds[index][1], 1) == -1) { perror("dup2(fds[index][1], 1) failed"); exit(1); } } //Handle output redirection else if (index == (num_commands - 1) && cmd.output_redirect_filename != NULL) { int output_fd; //Open file if it already exists if (fileExists(cmd.output_redirect_filename) == true) { if (cmd.output_append_flag == true) { output_fd = open(cmd.output_redirect_filename, O_WRONLY | O_APPEND); } else { output_fd = open(cmd.output_redirect_filename, O_WRONLY | O_TRUNC); } } //Create file if it doesn't exist else { output_fd = open(cmd.output_redirect_filename, O_WRONLY | O_CREAT, 0777); } if (output_fd == -1) { perror("open output file failed"); exit(1); } if (dup2(output_fd, 1) == -1) { perror("dup2(output_fd, 1) failed"); exit(1); } } closeAllPipes(fds, num_commands); execvp(cmd.argv[0], cmd.argv); perror("Command execution failed"); exit(1); }