Line data Source code
1 : #include "redirection.h" 2 : 3 12 : void handle_input_redirection(const Command *command) { 4 12 : if (command->redirection.input_file == NULL) return; 5 : 6 : int in; 7 2 : if (command->redirection.append_input) { // If the "<<" operator was used 8 : // Create a temporary file 9 1 : in = open("/tmp/redirection_input", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); 10 : 11 : // Read lines from the terminal until the delimiter is encountered 12 : char line[256]; 13 : while (1) { 14 2 : printf("> "); // Print the prompt symbol 15 2 : fflush(stdout); // Ensure the prompt is displayed immediately 16 2 : if (fgets(line, sizeof(line), stdin) == NULL) { 17 0 : break; // End of input 18 : } 19 : 20 : // Remove newline character from the end of the line 21 2 : line[strcspn(line, "\n")] = '\0'; 22 : 23 2 : if (strcmp(line, command->redirection.input_file) == 0) { 24 1 : break; // End of here document 25 : } 26 : 27 1 : write(in, line, strlen(line)); 28 1 : write(in, "\n", 1); // Add newline character back when writing to the file 29 : } 30 : 31 : 32 : // Close the file and reopen it for reading 33 1 : close(in); 34 1 : in = open("/tmp/redirection_input", O_RDONLY); 35 : } else { // If the "<" operator was used 36 1 : in = open(command->redirection.input_file, O_RDONLY); 37 : } 38 2 : dup2(in, STDIN_FILENO); 39 2 : close(in); 40 : } 41 : 42 12 : void handle_output_redirection(const Command *command) { 43 12 : if (command->redirection.output_file == NULL) return; 44 : 45 : int out; 46 2 : if (command->redirection.append_output) { // If the ">>" operator was used 47 1 : out = open(command->redirection.output_file, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); 48 : } else { // If the ">" operator was used 49 1 : out = open(command->redirection.output_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); 50 : } 51 2 : dup2(out, STDOUT_FILENO); 52 2 : close(out); 53 : } 54 : 55 20 : void evaluate_redirection(CommandSequence *sequence) 56 : { 57 31 : for (int i = 0; i < sequence->num_commands-1; ++i) { 58 11 : Command *cmd = &sequence->commands[i]; 59 : 60 : // Get the operator between the current command and the next one 61 11 : char *operator = sequence->operators[i]; 62 : 63 11 : if (strcmp(operator, "<") == 0) { 64 : // Input redirection 65 1 : if (i < sequence->num_commands - 1) { 66 1 : Command *next_cmd = &sequence->commands[i + 1]; 67 1 : cmd->redirection.input_file = strdup(next_cmd->command); 68 : } else { 69 0 : fprintf(stderr, "Missing command after input redirection\n"); 70 0 : break; 71 : } 72 10 : } else if (strcmp(operator, "<<") == 0) { 73 : // Input redirection (append) 74 1 : if (i < sequence->num_commands - 1) { 75 1 : Command *next_cmd = &sequence->commands[i + 1]; 76 1 : cmd->redirection.input_file = strdup(next_cmd->command); 77 1 : cmd->redirection.append_input = 1; 78 : } else { 79 0 : fprintf(stderr, "Missing command after input redirection\n"); 80 0 : break; 81 : } 82 : } 83 9 : else if (strcmp(operator, ">") == 0) { 84 : // Output redirection 85 1 : if (i < sequence->num_commands - 1) { 86 1 : Command *next_cmd = &sequence->commands[i + 1]; 87 1 : cmd->redirection.output_file = strdup(next_cmd->command); 88 : } else { 89 0 : fprintf(stderr, "Missing command after output redirection\n"); 90 0 : break; 91 : } 92 8 : } else if (strcmp(operator, ">>") == 0) { 93 : // Output redirection (append) 94 1 : if (i < sequence->num_commands - 1) { 95 1 : Command *next_cmd = &sequence->commands[i + 1]; 96 1 : cmd->redirection.output_file = strdup(next_cmd->command); 97 1 : cmd->redirection.append_output = 1; 98 : } else { 99 0 : fprintf(stderr, "Missing command after output redirection\n"); 100 0 : break; 101 : } 102 : } 103 : } 104 20 : } 105 : 106 24 : int is_redirection_command(const Command *command) 107 : { 108 24 : return command->redirection.input_file != NULL || command->redirection.output_file != NULL; 109 : } 110 : 111 1 : void execute_pipe(Command *cmd1, Command *cmd2) 112 : { 113 : int pipefd[2]; 114 : pid_t p1, p2; 115 : 116 1 : if (pipe(pipefd) < 0) { 117 0 : perror("pipe"); 118 0 : exit(EXIT_FAILURE); 119 : } 120 1 : p1 = fork(); 121 2 : if (p1 < 0) { 122 0 : perror("fork"); 123 0 : exit(EXIT_FAILURE); 124 : } 125 : 126 2 : if (p1 == 0) { 127 : // Child 1 executing.. 128 : // It only needs to write at the write end 129 1 : close(pipefd[0]); 130 1 : dup2(pipefd[1], STDOUT_FILENO); 131 1 : close(pipefd[1]); 132 : 133 1 : if (execvp(cmd1->command, cmd1->complete_command) < 0) { 134 0 : perror(cmd1->command); 135 0 : exit(EXIT_FAILURE); 136 : } 137 : } else { 138 : // Parent executing 139 1 : p2 = fork(); 140 : 141 2 : if (p2 < 0) { 142 0 : perror("fork"); 143 0 : exit(EXIT_FAILURE); 144 : } 145 : 146 : // Child 2 executing.. 147 : // It only needs to read at the read end 148 2 : if (p2 == 0) { 149 1 : close(pipefd[1]); 150 1 : dup2(pipefd[0], STDIN_FILENO); 151 1 : close(pipefd[0]); 152 1 : if (execvp(cmd2->command, cmd2->complete_command) < 0) { 153 0 : perror(cmd2->command); 154 0 : exit(EXIT_FAILURE); 155 : } 156 : } else { 157 : // parent executing, waiting for two children 158 1 : close(pipefd[0]); 159 1 : close(pipefd[1]); 160 1 : wait(NULL); 161 1 : wait(NULL); 162 : } 163 : } 164 3 : }