fix(execution): Reimplemented the redirection logic

This commit is contained in:
Jean 2026-01-29 18:18:04 +01:00
parent a98161d885
commit ec63be42e5
4 changed files with 75 additions and 32 deletions

View file

@ -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;
}

View file

@ -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)
{

View file

@ -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

View file

@ -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);