From 6bc2eab19b2bf55c63d8e733b0aff238313a570e Mon Sep 17 00:00:00 2001 From: marcnava-42cursus Date: Thu, 12 Feb 2026 20:28:05 +0100 Subject: [PATCH] feat: Redirections applied Now redirections work. > redirects to a file < reads the content of a file and set it to the input of a command >> append the output of a command into a file --- adios | 1 + hola | 1 + include/executor.h | 4 ++ minishell_tester | 1 + out | 1 + src/executor/executor.c | 8 ++- src/executor/process_helpers.c | 15 +++++ src/executor/redirections.c | 111 +++++++++++++++++++++++++++++++++ 8 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 adios create mode 100644 hola create mode 160000 minishell_tester create mode 100644 out create mode 100644 src/executor/redirections.c diff --git a/adios b/adios new file mode 100644 index 0000000..5aefe51 --- /dev/null +++ b/adios @@ -0,0 +1 @@ +dfsa diff --git a/hola b/hola new file mode 100644 index 0000000..8093d87 --- /dev/null +++ b/hola @@ -0,0 +1 @@ +fds diff --git a/include/executor.h b/include/executor.h index a8a9416..d91de93 100644 --- a/include/executor.h +++ b/include/executor.h @@ -52,5 +52,9 @@ extern void executor_child_process(t_list *node, t_pipeline *pl, extern void executor_parent_cleanup(t_list *node, t_pipeline *pl); extern uint8_t executor_wait_for_children(pid_t last_child_pid); extern void executor_cmdfree(t_command *command); +extern bool executor_apply_redirections(const t_command *command, + int *saved_stdin, int *saved_stdout); +extern void executor_restore_redirections(int saved_stdin, + int saved_stdout); #endif /* EXECUTOR_H */ diff --git a/minishell_tester b/minishell_tester new file mode 160000 index 0000000..67d136e --- /dev/null +++ b/minishell_tester @@ -0,0 +1 @@ +Subproject commit 67d136e972d97ae2d3e5db8f4e3998618523e479 diff --git a/out b/out new file mode 100644 index 0000000..4099407 --- /dev/null +++ b/out @@ -0,0 +1 @@ +23 diff --git a/src/executor/executor.c b/src/executor/executor.c index 9ef3eca..645b106 100644 --- a/src/executor/executor.c +++ b/src/executor/executor.c @@ -47,6 +47,8 @@ static bool run_current_command( { bool should_fork; t_command *command; + int saved_stdin; + int saved_stdout; if (executor_create_pipe_if_needed(state->current_command, &state->pipeline) == PIPE_ERROR) @@ -61,7 +63,11 @@ static bool run_current_command( else { command = state->current_command->content; - state->exit_status = executor_execute_command(command, minishell); + if (!executor_apply_redirections(command, &saved_stdin, &saved_stdout)) + state->exit_status = EXIT_FAILURE; + else + state->exit_status = executor_execute_command(command, minishell); + executor_restore_redirections(saved_stdin, saved_stdout); } executor_parent_cleanup(state->current_command, &state->pipeline); state->current_command = state->current_command->next; diff --git a/src/executor/process_helpers.c b/src/executor/process_helpers.c index d1db072..e34fc1e 100644 --- a/src/executor/process_helpers.c +++ b/src/executor/process_helpers.c @@ -24,6 +24,8 @@ void executor_child_process( command = current_command->content; executor_setup_child_input(pipeline); executor_setup_child_output(current_command, pipeline); + if (!executor_apply_redirections(command, NULL, NULL)) + exit(EXIT_FAILURE); exit_status = executor_execute_command(command, minishell); exit(exit_status); } @@ -85,6 +87,16 @@ static void cmdfree_argv( free(argv); } +static void cmdfree_redirection( + t_redirection *redirection +) +{ + if (redirection == NULL) + return ; + free(redirection->target); + free(redirection); +} + void executor_cmdfree( t_command *command ) @@ -93,5 +105,8 @@ void executor_cmdfree( return ; cmdfree_argv(command->argv); free(command->path); + ft_lstclear(&command->redirections, + (void (*)(void *))cmdfree_redirection); + ft_lstclear(&command->heredocs, (void (*)(void *))cmdfree_redirection); free(command); } diff --git a/src/executor/redirections.c b/src/executor/redirections.c new file mode 100644 index 0000000..5ce94c2 --- /dev/null +++ b/src/executor/redirections.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirections.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: sede-san + +static int open_redirection_target( + const t_redirection *redirection +) +{ + if (redirection->type == TOKEN_REDIRECT_IN) + return (open(redirection->target, O_RDONLY)); + if (redirection->type == TOKEN_REDIRECT_OUT) + return (open(redirection->target, O_WRONLY | O_CREAT | O_TRUNC, 0644)); + if (redirection->type == TOKEN_APPEND) + return (open(redirection->target, O_WRONLY | O_CREAT | O_APPEND, 0644)); + errno = EINVAL; + return (-1); +} + +static bool backup_stream_if_needed( + const t_redirection *redirection, + int *saved_stdin, + int *saved_stdout +) +{ + if (redirection->type == TOKEN_REDIRECT_IN && saved_stdin != NULL + && *saved_stdin == -1) + { + *saved_stdin = dup(STDIN_FILENO); + if (*saved_stdin == -1) + return (perror("dup"), false); + } + if ((redirection->type == TOKEN_REDIRECT_OUT + || redirection->type == TOKEN_APPEND) && saved_stdout != NULL + && *saved_stdout == -1) + { + *saved_stdout = dup(STDOUT_FILENO); + if (*saved_stdout == -1) + return (perror("dup"), false); + } + return (true); +} + +bool executor_apply_redirections( + const t_command *command, + int *saved_stdin, + int *saved_stdout +) +{ + t_list *node; + t_redirection *redirection; + int fd; + + if (saved_stdin != NULL) + *saved_stdin = -1; + if (saved_stdout != NULL) + *saved_stdout = -1; + if (command == NULL || command->redirections == NULL) + return (true); + node = command->redirections; + while (node != NULL) + { + redirection = (t_redirection *)node->content; + if (redirection == NULL || redirection->target == NULL) + return (false); + if (!backup_stream_if_needed(redirection, saved_stdin, saved_stdout)) + return (false); + fd = open_redirection_target(redirection); + if (fd == -1) + return (perror(redirection->target), false); + if (redirection->type == TOKEN_REDIRECT_IN + && dup2(fd, STDIN_FILENO) == -1) + return (close(fd), perror("dup2"), false); + if ((redirection->type == TOKEN_REDIRECT_OUT + || redirection->type == TOKEN_APPEND) + && dup2(fd, STDOUT_FILENO) == -1) + return (close(fd), perror("dup2"), false); + close(fd); + node = node->next; + } + return (true); +} + +void executor_restore_redirections( + int saved_stdin, + int saved_stdout +) +{ + if (saved_stdin != -1) + { + if (dup2(saved_stdin, STDIN_FILENO) == -1) + perror("dup2"); + close(saved_stdin); + } + if (saved_stdout != -1) + { + if (dup2(saved_stdout, STDOUT_FILENO) == -1) + perror("dup2"); + close(saved_stdout); + } +}