【发布时间】:2013-07-11 16:10:59
【问题描述】:
我正在尝试在 C 中实现多管道,以像 shell 一样运行多个命令。 我制作了一个链接列表(在我的代码中称为 t_launch),如果您键入“ls | grep src | wc”,它看起来像这样:
wc -- 管道 -- grep src -- 管道 -- ls
每个 PIPE 节点都包含一个来自 pipe() 函数的 int tab[2](当然,每个 PIPE 节点都有一个 pipe() 调用)
现在我正在尝试执行这些命令:
int execute_launch_list(t_shell *shell, t_launch *launchs)
{
pid_t pid;
int status;
int firstpid;
firstpid = 0;
while (launchs != NULL)
{
if ((pid = fork()) == -1)
return (my_error("Unable to fork\n"));
if (pid == 0)
{
if (launchs->prev != NULL)
{
close(1);
dup2(launchs->prev->pipefd[1], 1);
close(launchs->prev->pipefd[0]);
}
if (launchs->next != NULL)
{
close(0);
dup2(launchs->next->pipefd[0], 0);
close(launchs->next->pipefd[1]);
}
execve(launchs->cmdpath, launchs->words, shell->environ);
}
else if (firstpid == 0)
firstpid = pid;
launchs = launchs->next == NULL ? launchs->next : launchs->next->next;
}
waitpid(firstpid, &status, 0);
return (SUCCESS);
}
但这不起作用:看起来命令不会停止读取。 例如,如果我输入“ls | grep src”,“src”将从 grep 命令中打印出来,但 grep 会继续读取并且永远不会停止。如果我输入“ls | grep 源代码 | wc”,没有打印任何内容。我的代码有什么问题? 谢谢。
【问题讨论】:
-
你能解释一下
launchs = launchs->next == NULL ? launchs->next : launchs->next->next;吗?我错过了 sonethin 还是你跳过了每个第二个子进程? -
我跳过节点“PIPE”:链表看起来像“grep -- PIPE -- ls”,所以在我做了“grep stuff”之后,我转到“ls”,所以它是 - >next->next(单个 next 将把我带到管道节点上)
-
谢谢我现在明白了。我猜 rici 是对的:客户端应该从
launch->prev获取stdin并将stdout重定向到launchs->next。 ...哎呀,他的评论被删除了,但是... -
@IngoLeonhardt:我删除它是因为我看到列表的顺序是从右到左,所以next和prev是正确的。
-
@rici 我现在的失明已经痊愈了,顺便说一句。好的答案,算法,忘记我的最后评论,看看 rici 的答案