From 4315eb5c0d5011ea483c5bef4e8e470cb04f8295 Mon Sep 17 00:00:00 2001 From: Jean <47366872+jean-voila@users.noreply.github.com> Date: Thu, 29 Jan 2026 19:12:58 +0100 Subject: [PATCH] fix(execution): Redir ahah type --- src/execution/execution_helpers.c | 305 ++++++++++++++++-------------- src/execution/execution_helpers.h | 2 + 2 files changed, 162 insertions(+), 145 deletions(-) diff --git a/src/execution/execution_helpers.c b/src/execution/execution_helpers.c index cffcdb0..501b159 100644 --- a/src/execution/execution_helpers.c +++ b/src/execution/execution_helpers.c @@ -16,137 +16,6 @@ #include "../utils/vars/vars.h" #include "execution.h" -static char **list_to_argv(struct list *command_list) -{ - size_t len = 0; - struct list *cur = command_list; - while (cur) - { - len++; - cur = cur->next; - } - char **argv = calloc(len + 1, sizeof(char *)); - if (!argv) - return NULL; - cur = command_list; - for (size_t i = 0; i < len; i++) - { - argv[i] = (char *)cur->data; - cur = cur->next; - } - argv[len] = NULL; - return argv; -} - -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; -} - -int exec_ast_if(struct ast_if *if_node, struct hash_map *vars) -{ - int cond = execution(if_node->condition, vars); - if (cond == 0) - return execution(if_node->then_clause, vars); - else - return execution(if_node->else_clause, vars); -} - -int exec_ast_list(struct ast_list *list_node, struct hash_map *vars) -{ - struct list *cur = list_node->children; - int ret = 0; - while (cur) - { - struct ast *child = (struct ast *)cur->data; - if (!ast_is_void(child)) - ret = execution(child, vars); - cur = cur->next; - } - return ret; -} - -int exec_ast_and_or(struct ast_and_or *ao_node, struct hash_map *vars) -{ - int left_ret = execution(ao_node->left, vars); - if (ao_node->type == AST_AND_OR_TYPE_AND) - { - if (left_ret == 0) - return execution(ao_node->right, vars); - return left_ret; - } - else - { - if (left_ret != 0) - return execution(ao_node->right, vars); - return left_ret; - } -} - -static int get_fd_target(const struct ast_redir *redir) -{ - if (redir->io_number != -1) - return redir->io_number; - if (redir->type == AST_REDIR_TYPE_LESS - || redir->type == AST_REDIR_TYPE_LESSGREAT - || redir->type == AST_REDIR_TYPE_LESSAND) - return 0; - return 1; -} - static int open_redir_file(const struct ast_redir *redir, int *flags, int *mode) { *mode = 0644; @@ -169,20 +38,6 @@ static int open_redir_file(const struct ast_redir *redir, int *flags, int *mode) return -3; // not a file open } -static int handle_and_restore_fd(int saved_fd, int fd_target) -{ - if (saved_fd != -1) - { - dup2(saved_fd, fd_target); - close(saved_fd); - } - else - { - close(fd_target); - } - return 0; -} - static int set_all_redir(struct list *redir_list) { while (redir_list) @@ -248,6 +103,166 @@ static int set_all_redir(struct list *redir_list) return 0; } +static char **list_to_argv(struct list *command_list) +{ + size_t len = 0; + struct list *cur = command_list; + while (cur) + { + len++; + cur = cur->next; + } + char **argv = calloc(len + 1, sizeof(char *)); + if (!argv) + return NULL; + cur = command_list; + for (size_t i = 0; i < len; i++) + { + argv[i] = (char *)cur->data; + cur = cur->next; + } + argv[len] = NULL; + return argv; +} + +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 ? command->redirections->children + : NULL); + + if (!command || !(command->command)) + { + return 1; + } + + char **argv = list_to_argv(command->command); + if (!argv || !(argv[0])) + { + free(argv); + unset_all_redir(command->redirections ? command->redirections->children + : NULL); + return 0; + } + + int builtin_ret = try_builtin(argv, vars); + if (builtin_ret != -1) + { + free(argv); + unset_all_redir(command->redirections ? command->redirections->children + : NULL); + return builtin_ret; + } + + pid_t pid = fork(); + if (pid < 0) + { + perror("fork"); + free(argv); + unset_all_redir(command->redirections ? command->redirections->children + : NULL); + return 1; + } + + if (pid == 0) + { + execvp(argv[0], argv); + perror("execvp"); + unset_all_redir(command->redirections ? command->redirections->children + : NULL); + _exit(127); + } + + int status = 0; + waitpid(pid, &status, 0); + free(argv); + unset_all_redir(command->redirections ? command->redirections->children + : NULL); + + if (WIFEXITED(status)) + { + return WEXITSTATUS(status); + } + + return 1; +} + +int exec_ast_if(struct ast_if *if_node, struct hash_map *vars) +{ + int cond = execution(if_node->condition, vars); + if (cond == 0) + return execution(if_node->then_clause, vars); + else + return execution(if_node->else_clause, vars); +} + +int exec_ast_list(struct ast_list *list_node, struct hash_map *vars) +{ + struct list *cur = list_node->children; + int ret = 0; + while (cur) + { + struct ast *child = (struct ast *)cur->data; + if (!ast_is_void(child)) + ret = execution(child, vars); + cur = cur->next; + } + return ret; +} + +int exec_ast_and_or(struct ast_and_or *ao_node, struct hash_map *vars) +{ + int left_ret = execution(ao_node->left, vars); + if (ao_node->type == AST_AND_OR_TYPE_AND) + { + if (left_ret == 0) + return execution(ao_node->right, vars); + return left_ret; + } + else + { + if (left_ret != 0) + return execution(ao_node->right, vars); + return left_ret; + } +} + +void unset_all_redir(struct list *redir_list) +{ + 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; + } + else + { + 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; + } + } + if (redir->saved_fd != -1) + { + dup2(redir->saved_fd, target_fd); + close(redir->saved_fd); + redir->saved_fd = -1; + } + + redir_list = redir_list->next; + } +} + /* 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 fd8026c..622c9fe 100644 --- a/src/execution/execution_helpers.h +++ b/src/execution/execution_helpers.h @@ -9,4 +9,6 @@ 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); +void unset_all_redir(struct list *redir_list); + #endif // EXECUTION_HELPERS_H