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
This commit is contained in:
@@ -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 void executor_parent_cleanup(t_list *node, t_pipeline *pl);
|
||||||
extern uint8_t executor_wait_for_children(pid_t last_child_pid);
|
extern uint8_t executor_wait_for_children(pid_t last_child_pid);
|
||||||
extern void executor_cmdfree(t_command *command);
|
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 */
|
#endif /* EXECUTOR_H */
|
||||||
|
|||||||
1
minishell_tester
Submodule
1
minishell_tester
Submodule
Submodule minishell_tester added at 67d136e972
@@ -47,6 +47,8 @@ static bool run_current_command(
|
|||||||
{
|
{
|
||||||
bool should_fork;
|
bool should_fork;
|
||||||
t_command *command;
|
t_command *command;
|
||||||
|
int saved_stdin;
|
||||||
|
int saved_stdout;
|
||||||
|
|
||||||
if (executor_create_pipe_if_needed(state->current_command,
|
if (executor_create_pipe_if_needed(state->current_command,
|
||||||
&state->pipeline) == PIPE_ERROR)
|
&state->pipeline) == PIPE_ERROR)
|
||||||
@@ -61,7 +63,11 @@ static bool run_current_command(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
command = state->current_command->content;
|
command = state->current_command->content;
|
||||||
|
if (!executor_apply_redirections(command, &saved_stdin, &saved_stdout))
|
||||||
|
state->exit_status = EXIT_FAILURE;
|
||||||
|
else
|
||||||
state->exit_status = executor_execute_command(command, minishell);
|
state->exit_status = executor_execute_command(command, minishell);
|
||||||
|
executor_restore_redirections(saved_stdin, saved_stdout);
|
||||||
}
|
}
|
||||||
executor_parent_cleanup(state->current_command, &state->pipeline);
|
executor_parent_cleanup(state->current_command, &state->pipeline);
|
||||||
state->current_command = state->current_command->next;
|
state->current_command = state->current_command->next;
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ void executor_child_process(
|
|||||||
command = current_command->content;
|
command = current_command->content;
|
||||||
executor_setup_child_input(pipeline);
|
executor_setup_child_input(pipeline);
|
||||||
executor_setup_child_output(current_command, 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_status = executor_execute_command(command, minishell);
|
||||||
exit(exit_status);
|
exit(exit_status);
|
||||||
}
|
}
|
||||||
@@ -85,6 +87,16 @@ static void cmdfree_argv(
|
|||||||
free(argv);
|
free(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cmdfree_redirection(
|
||||||
|
t_redirection *redirection
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (redirection == NULL)
|
||||||
|
return ;
|
||||||
|
free(redirection->target);
|
||||||
|
free(redirection);
|
||||||
|
}
|
||||||
|
|
||||||
void executor_cmdfree(
|
void executor_cmdfree(
|
||||||
t_command *command
|
t_command *command
|
||||||
)
|
)
|
||||||
@@ -93,5 +105,8 @@ void executor_cmdfree(
|
|||||||
return ;
|
return ;
|
||||||
cmdfree_argv(command->argv);
|
cmdfree_argv(command->argv);
|
||||||
free(command->path);
|
free(command->path);
|
||||||
|
ft_lstclear(&command->redirections,
|
||||||
|
(void (*)(void *))cmdfree_redirection);
|
||||||
|
ft_lstclear(&command->heredocs, (void (*)(void *))cmdfree_redirection);
|
||||||
free(command);
|
free(command);
|
||||||
}
|
}
|
||||||
|
|||||||
111
src/executor/redirections.c
Normal file
111
src/executor/redirections.c
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* redirections.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2026/02/12 00:00:00 by sede-san #+# #+# */
|
||||||
|
/* Updated: 2026/02/12 00:00:00 by sede-san ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "executor.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user