Why is my heredoc getting input from a redirection?

39 views Asked by At

I am building a program that behaves like bash while handling pipes, redirections, heredocs, etc.

I have an issue with my code, which is: Every time I run a command like cat << a | sort < a.txt, my heredoc does this:

minishell> cat << a | sort < a.txt
heredoc> this is also in a.txt
this is in a.txt

heredoc> a
minishell> 

I feel like there is some problem with my code timeline or something like this, but I can't figure out why. Here are some relevant parts of the code:

void    ft_executer(t_minishell *ms)
{
    int     i;
    t_cmd   *curr;

    i = 0;
    curr = ms->cmd_lst;
    ms->n_pipes = ft_count_pipes(ms->cmd_lst);
    if (ms->n_pipes == 0)
        ft_execute_only_cmd(ms, curr, curr->cmd);
    else
    {
        ft_set_cmd_index(ms);
        ft_open_pipes(ms);
        while (curr)
        {
            ft_execute_mult_cmd(ms, curr, curr->cmd);
            curr = curr->next;
        }
        ft_close_pipes(ms);
        while (i < ms->n_pipes + 1)
            waitpid(ms->pid[i++], NULL, 0);
    }
}

void    ft_execute_mult_cmd(t_minishell *ms, t_cmd *curr, char *cmd)
{
    if (curr->heredoc[0])
        waitpid(ms->pid_heredoc, NULL, 0);
    ms->pid[curr->index] = fork();
    if (ms->pid[curr->index] < 0)
        ft_perror(ms, E_FORK, YES);
    else if (ms->pid[curr->index] == 0)
    {
        if (ft_cmd_has_redir(curr) == YES)
            ft_handle_redir(ms, curr);
        ft_handle_pipes(ms, curr);
        ft_close_pipes(ms);
        ft_close_fds(curr);
        ft_execute_cmd(ms, curr, cmd);
    }
}

void    ft_handle_pipes(t_minishell *ms, t_cmd *curr)
{
    if (curr->index == 0)
    {
        dup2(curr->fd_in, STDIN_FILENO);
        dup2(ms->pipe_fd[curr->index][1], STDOUT_FILENO);
    }
    else if (curr->next == NULL || curr->fd_out > STDOUT_FILENO)
    {
        dup2(ms->pipe_fd[curr->index - 1][0], STDIN_FILENO);
        dup2(curr->fd_out, STDOUT_FILENO);
    }
    else
    {
        dup2(ms->pipe_fd[curr->index - 1][0], STDIN_FILENO);
        dup2(ms->pipe_fd[curr->index][1], STDOUT_FILENO);
    }
    if (curr->fd_in > STDIN_FILENO)
        dup2(curr->fd_in, STDIN_FILENO);
    if (curr->fd_out > STDOUT_FILENO)
        dup2(curr->fd_out, STDOUT_FILENO);
}

void    ft_handle_redir(t_minishell *ms, t_cmd *curr)
{
    int i;

    i = 0;
    while (curr->file_in[i])
        curr->fd_in = ft_perror_fd(ms, curr->file_in[i++], T_FILE_IN);
    i = 0;
    while (curr->file_tr[i])
        curr->fd_out = ft_perror_fd(ms, curr->file_tr[i++], T_FILE_TRUNC);
    i = 0;
    while (curr->file_ap[i])
        curr->fd_out = ft_perror_fd(ms, curr->file_ap[i++], T_FILE_APPEND);
    i = 0;
    while (curr->heredoc[i])
        curr->fd_in = ft_handle_heredoc(ms, curr->heredoc[i++]);
    dup2(curr->fd_in, STDIN_FILENO);
    dup2(curr->fd_out, STDOUT_FILENO);
}

int ft_perror_fd(t_minishell *ms, char *filename, t_type file_type)
{
    int fd;

    fd = 0;
    if (file_type == T_FILE_IN)
        fd = open(filename, O_RDONLY);
    else if (file_type == T_FILE_TRUNC)
        fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    else if (file_type == T_FILE_APPEND)
        fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644);
    if (fd < 0)
        ft_perror(ms, E_FILE, YES);
    return (fd);
}

int ft_handle_heredoc(t_minishell *ms, char *delimiter)
{
    ms->pid_heredoc = fork();
    if (ms->pid_heredoc < 0)
        ft_perror(ms, E_FORK, YES);
    else if (ms->pid_heredoc == 0)
        ft_create_heredoc(ms, delimiter);
    else
        waitpid(ms->pid_heredoc, NULL, 0);
    return (open(".heredoc", O_RDONLY));
}

void    ft_create_heredoc(t_minishell *ms, char *delimiter)
{
    int     fd;
    char    *line;

    fd = open(".heredoc", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    while (42)
    {
        line = readline("heredoc> ");
        if (!line)
        {
            ft_perror(ms, E_HEREDOC, YES);
            break ;
        }
        if (line && ft_strncmp(line, delimiter, ft_strlen(line) + 1) == 0)
        {
            free(line);
            break ;
        }
        line = ft_expand_heredoc(ms, line);
        ft_putendl_fd(line, fd);
        free(line);
    }
    close(fd);
    if (ms->n_pipes > 0)
        ft_free_pipes(ms);
    ft_free_all(ms, YES);
}
0

There are 0 answers