Files
minishell/src/executor/redirections.c
marcnava-42cursus 6bc2eab19b 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
2026-02-12 20:28:05 +01:00

112 lines
3.2 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* 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);
}
}