为什么我的 heredoc 会从重定向中获得输入?

Why is my heredoc getting input from a redirection?

提问人:nobody really 提问时间:10/5/2023 更新时间:10/5/2023 访问量:30

问:

我正在构建一个程序,在处理管道、重定向、heredocs 等时表现得像 bash。

我的代码有问题,那就是: 每次我运行像 cat << |有点像.txt,我的 HereDoc <这样做:

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

heredoc> a
minishell> 

我觉得我的代码时间线或类似的东西有些问题,但我不知道为什么。以下是代码的一些相关部分:

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);
}
C HereDoc

评论

0赞 Oka 10/5/2023
按原样,任何人都不太可能/愿意帮助您解决这个问题,因为您的问题缺乏有效的最小可重复示例。我敢打赌,很少有人能立即访问完整的库,并且期望其他人自己提供这些函数和/或视读您的代码(并对其中的大部分内容做出假设)并不是寻求帮助的好方法。一般的建议是阅读如何调试小程序,并尝试更精确地隔离您的问题。ft_

答: 暂无答案