From 6948bbae63e388befe6f6814d982cd391200476d Mon Sep 17 00:00:00 2001 From: Jean <47366872+jean-voila@users.noreply.github.com> Date: Thu, 29 Jan 2026 18:18:04 +0100 Subject: [PATCH] fix(execution): Reimplemented the redirection logic --- src/execution/execution.c | 5 +- src/execution/execution_helpers.c | 100 ++++++++++++++++++++++-------- src/execution/execution_helpers.h | 1 - src/utils/ast/ast_redir.h | 1 + 4 files changed, 75 insertions(+), 32 deletions(-) diff --git a/src/execution/execution.c b/src/execution/execution.c index 90bb8eb..cf751f7 100644 --- a/src/execution/execution.c +++ b/src/execution/execution.c @@ -14,8 +14,6 @@ #include "../utils/ast/ast.h" #include "../utils/hash_map/hash_map.h" - - // Refactored: delegates to helpers in execution_helpers.c #include "execution_helpers.h" @@ -33,6 +31,7 @@ int execution(struct ast *ast, struct hash_map *vars) struct ast_command *command = ast_get_command(ast); if (!expand(command, vars)) fprintf(stderr, "Error: Variable expansion failed\n"); + return exec_ast_command(command, vars); } case AST_IF: @@ -41,8 +40,6 @@ int execution(struct ast *ast, struct hash_map *vars) return exec_ast_list(ast_get_list(ast), vars); case AST_AND_OR: return exec_ast_and_or(ast_get_and_or(ast), vars); - case AST_REDIR: - return exec_ast_redir(ast_get_redir(ast), vars); default: return 127; } diff --git a/src/execution/execution_helpers.c b/src/execution/execution_helpers.c index 8ea5aef..aba6dc7 100644 --- a/src/execution/execution_helpers.c +++ b/src/execution/execution_helpers.c @@ -12,6 +12,7 @@ #include "../expansion/expansion.h" #include "../utils/ast/ast.h" #include "../utils/hash_map/hash_map.h" +#include "../utils/lists/lists.h" #include "../utils/vars/vars.h" #include "execution.h" @@ -42,40 +43,56 @@ static int try_builtin(char **argv, struct hash_map *vars); int exec_ast_command(struct ast_command *command, struct hash_map *vars) { (void)vars; + set_all_redir(command->redirections); + if (!command || !(command->command)) + { return 1; + } + char **argv = list_to_argv(command->command); if (!argv || !(argv[0])) { free(argv); + unset_all_redir(); return 0; } + int builtin_ret = try_builtin(argv, vars); if (builtin_ret != -1) { free(argv); + unset_all_redir(); return builtin_ret; } + pid_t pid = fork(); if (pid < 0) { perror("fork"); free(argv); + unset_all_redir(); return 1; } + if (pid == 0) { execvp(argv[0], argv); perror("execvp"); + unset_all_redir(); _exit(127); } + int status = 0; waitpid(pid, &status, 0); free(argv); + unset_all_redir(); + if (WIFEXITED(status)) { return WEXITSTATUS(status); } + return 1; } @@ -166,42 +183,71 @@ static int handle_and_restore_fd(int saved_fd, int fd_target) return 0; } -/* - -static open_all_redir(const struct ast_list redir_list) +static int set_all_redir(struct list *redir_list) { - while (redir_list){ - struct ast_redir *redir = (struct ast_redir*)redir_list->data; + while (redir_list) + { + struct ast_redir *redir = (struct ast_redir *)redir_list->data; int target_fd; + if (redir->io_number != -1) { - target_fd = redir->io_number; + target_fd = redir->io_number; + } + else + { + // assign target_fd depending on redir type + if (redir->type == AST_REDIR_TYPE_LESS + || redir->type == AST_REDIR_TYPE_LESSGREAT + || redir->type == AST_REDIR_TYPE_LESSAND) + { + target_fd = 0; + } + else + { + target_fd = 1; + } } - else - { - // assign target_fd depending on redir type - } - int saved_fd = dup(target_fd); - - // if redir type is not with '&' - // then we open("filename") - // else, no need to open, just new_fd = atoi(filename) - - open(); - - dup2(target_fd, new_fd); - - close(new_fd); - - // append target_fd and saved_fd to a list - // in order to be able to restore all the fds + redir->saved_fd = dup(target_fd); + int new_fd = -1; + int flags = 0; + int mode = 0644; + if (redir->type == AST_REDIR_TYPE_GREAT + || redir->type == AST_REDIR_TYPE_CLOBBER + || redir->type == AST_REDIR_TYPE_DGREAT + || redir->type == AST_REDIR_TYPE_LESS) + { + new_fd = open_redir_file(redir, &flags, &mode); + if (new_fd == -1) + { + perror("open"); + return -1; + } + } + else if (redir->type == AST_REDIR_TYPE_GREATAND + || redir->type == AST_REDIR_TYPE_LESSAND) + { + new_fd = atoi(redir->filename); + } + if (dup2(new_fd, target_fd) == -1) + { + perror("dup2"); + if (new_fd != -1) + { + close(new_fd); + } + return -1; + } + if (new_fd != -1) + { + close(new_fd); + } + redir_list = redir_list->next; } - + return 0; } - -*/ /* int exec_ast_redir(struct ast_redir *redir, struct hash_map *vars) { diff --git a/src/execution/execution_helpers.h b/src/execution/execution_helpers.h index ebac0cb..fd8026c 100644 --- a/src/execution/execution_helpers.h +++ b/src/execution/execution_helpers.h @@ -8,6 +8,5 @@ int exec_ast_command(struct ast_command *command, struct hash_map *vars); int exec_ast_if(struct ast_if *if_node, struct hash_map *vars); int exec_ast_list(struct ast_list *list_node, struct hash_map *vars); int exec_ast_and_or(struct ast_and_or *ao_node, struct hash_map *vars); -int exec_ast_redir(struct ast_redir *redir, struct hash_map *vars); #endif // EXECUTION_HELPERS_H diff --git a/src/utils/ast/ast_redir.h b/src/utils/ast/ast_redir.h index fdea88c..9d9a9d3 100644 --- a/src/utils/ast/ast_redir.h +++ b/src/utils/ast/ast_redir.h @@ -21,6 +21,7 @@ struct ast_redir int io_number; // The FD being redirected (default -1 if not specified, // implies 0 or 1 based on type) enum ast_redir_type type; + int saved_fd; // To store the original FD for restoration (-1 before save) }; bool ast_is_redir(struct ast *node);