C语言 为什么管道不为猫工作|猫|什么?

o8x7eapl  于 2023-04-05  发布在  其他
关注(0)|答案(1)|浏览(105)

我真的需要帮助,任何建议都将受到欢迎。我和一个伙伴编写了一个小型版本的Shell,我做了解析和执行部分。所有工作正常,除了一些情况下,可能是隐藏了一些逻辑,我不能捕捉,我实际上卡住了。特别是在启动cat | cat | ls cmd时,ls输出正常,但cat行为不是预期的。(没有任何参数)突然返回提示符。这可能意味着管道没有在正确的位置关闭,但是我找不到具体的位置。下面你会找到执行部分。如果任何人请能帮助与善良和非竞争的态度将非常感谢.这里是github仓库的任何进一步的细节GitHub Repo

void    executing_commands(t_minish *data)
{
    t_cmd   *cmd;
    int process_status;

    process_status = 0;
    cmd = data->cmds;
    if (!cmd->full_cmd)
    return ;
    creating_pipes(data);
    while (cmd && cmd->full_cmd)
    cmd = creating_child(&cmd, data);
    closing_all_fd(data);
    cmd = data->cmds;
    while (cmd)
    {
        waitpid(data->child, &process_status, 0);
        if (data->cmds && !check_parent_builtin(&cmd))
            g_status = WEXITSTATUS(process_status);
        cmd = cmd->next;
    }
}

t_cmd   *creating_child(t_cmd **cmd, t_minish *data)
{
    int pid;

    if (check_parent_builtin(cmd))
        executing_builtin(data, cmd);
    else
    {
        pid = fork();
        if (ft_memcmp((*cmd)->full_cmd[0], "minishell", 10))
            set_signals(EXEC);
        data->child = pid;
        if (pid == -1)
        {
            closing_all_fd(data);
            error_manager(2, data, NULL);
        }
        else if (pid == 0)
            child_process(data, cmd);
    }
    return ((*cmd)->next);
}

void    child_process(t_minish *data, t_cmd **cmd)
{
    switching_input_output(data, cmd);
    closing_all_fd(data);
    if (check_child_builtin(cmd))
        executing_builtin(data, cmd);
    else
        launching_command(data, cmd);
}

void    switching_input_output(t_minish *data, t_cmd **cmd)
{
    if ((*cmd)->output > 1)
    {
        if (dup2((*cmd)->output, STDOUT_FILENO) < 0)
            error_manager(6, data, cmd);
        close((*cmd)->output);
    }
    if ((*cmd)->input)
    {
        if (dup2((*cmd)->input, STDIN_FILENO) < 0)
            error_manager(6, data, cmd);
        close((*cmd)->input);
    }
    if ((*cmd)->file_in)
    {
        if (dup2((*cmd)->file_in, STDIN_FILENO) < 0)
            error_manager(6, data, cmd);
        close((*cmd)->file_in);
    }
    if ((*cmd)->file_out)
    {
        if (dup2((*cmd)->file_out, STDOUT_FILENO) < 0)
            error_manager(6, data, cmd);
        close((*cmd)->file_out);
    }
}

void    launching_command(t_minish *data, t_cmd **cmd)
{
    if (execve((*cmd)->full_path, (*cmd)->full_cmd, data->env_table) == -1)
        error_manager(3, data, cmd);
}

void    closing_all_fd(t_minish *data)
{
    t_cmd   *cmd;

    cmd = data->cmds;
    while (cmd)
    {
        if (cmd->input)
            close(cmd->input);
        if (cmd->output > 1)
            close(cmd->output);
        cmd = cmd->next;
    }
}

void    closing_fd_if_redirections(t_minish *data)
{
    t_cmd   *cmd;

    cmd = data->cmds;
    while (cmd)
    {
        if (cmd->file_in && cmd->input)
            close(cmd->input);
        cmd = cmd->next;
    }
}

void    creating_pipes(t_minish *data)
{
    int     fd[2];
    t_cmd   *cmd;

    cmd = data->cmds;
    while (cmd->next != NULL)
    {
        if (pipe(fd) == -1)
            error_manager(1, data, NULL);
        cmd->output = fd[1];
        cmd->next->input = fd[0];
        if (!cmd->next->next)
            cmd->next->last = 1;
        cmd = cmd->next;
    }
    closing_fd_if_redirections(data);
}

我试图不创建所有的管道需要所有的突然为了更好地控制关闭在父进程和子进程只是一个管道为每个循环但仍然没有工作

wlzqhblo

wlzqhblo1#

...突然返回提示。这可能意味着管道没有在正确的位置关闭...
你的概率估计出错了。错误是shell没有等待管道中的所有命令,因为,尽管你正确地尝试在executing_commands中等待while (cmd)循环中的每个命令,但整个管道只有一个存储位置data->child,所以一个子PID被以下命令覆盖,最后shell只能等待最后一个命令。
当然,补救措施是按cmd存储child,而不是按data存储。

相关问题