我真的需要帮助,任何建议都将受到欢迎。我和一个伙伴编写了一个小型版本的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);
}
我试图不创建所有的管道需要所有的突然为了更好地控制关闭在父进程和子进程只是一个管道为每个循环但仍然没有工作
1条答案
按热度按时间wlzqhblo1#
...突然返回提示。这可能意味着管道没有在正确的位置关闭...
你的概率估计出错了。错误是shell没有等待管道中的所有命令,因为,尽管你正确地尝试在
executing_commands
中等待while (cmd)
循环中的每个命令,但整个管道只有一个存储位置data->child
,所以一个子PID被以下命令覆盖,最后shell只能等待最后一个命令。当然,补救措施是按
cmd
存储child
,而不是按data
存储。