为什么我的管道仅在我发送 SIGINT 时才结束
Why my pipe ends only when i send a SIGINT
基本上,我正在用 C 写一个 shell..
我正在尝试实现管道功能,这几乎完成了:
> ls | cat -e | wc | wc -l
> 1
但是我在尝试通过管道进行更多 slower/longer 执行时遇到了问题。
确实,当我尝试通过管道传输 'cat /dev/urandom' 的结果时,它基本上会等待...
> cat /dev/urandom | cat
>
但是,当我发送 SIGINT(使用 ctrl + c)停止它时,它会在 STDOUT 上打印结果缓冲区..
when i ctrl + c , cat /dev/urandom
所以我的问题是:我应该查看哪里来尝试修复此问题?
我的管道执行部分:
int exec_apipe(t_me *me, t_node *curs, int is_last)
{
int pfd[2];
int pid;
if (pipe(pfd) == -1 || !curs)
return (0);
if (!(curs->pid = fork()))
{
dup2(me->fd_in, 0);
me->fd_in > 0 ? close(me->fd_in) : 0;
if (!is_last)
dup2(pfd[1], 1);
else if (curs->parent->parent && curs->parent->parent->fd_out >= 0)
dup2(curs->parent->parent->fd_out, 1);
close(pfd[0]);
exec_mpipe(me, curs);
exit(-1);
}
else if (curs->pid > 0)
{
waitpid(curs->pid, &(curs->ret), WUNTRACED);
handle_pid(me, curs->ret);
close(pfd[1]);
me->fd_in = pfd[0];
}
return (pid >= 0 ? 1 : -1);
}
我希望有人能理解我在说什么,也许能帮上忙..
谢谢
在等待 任何 个程序完成之前,您需要启动管道中的所有 个程序。
您的 shell 实现正在等待每个管道元素完成,然后再开始下一个。但是/dev/urandom
是源源不断的; cat /dev/urandom
会 运行 直到被杀死。所以第二个 cat
永远不会开始,直到你 control-C 第一个。
基本上,我正在用 C 写一个 shell.. 我正在尝试实现管道功能,这几乎完成了:
> ls | cat -e | wc | wc -l
> 1
但是我在尝试通过管道进行更多 slower/longer 执行时遇到了问题。
确实,当我尝试通过管道传输 'cat /dev/urandom' 的结果时,它基本上会等待...
> cat /dev/urandom | cat
>
但是,当我发送 SIGINT(使用 ctrl + c)停止它时,它会在 STDOUT 上打印结果缓冲区..
when i ctrl + c , cat /dev/urandom
所以我的问题是:我应该查看哪里来尝试修复此问题?
我的管道执行部分:
int exec_apipe(t_me *me, t_node *curs, int is_last)
{
int pfd[2];
int pid;
if (pipe(pfd) == -1 || !curs)
return (0);
if (!(curs->pid = fork()))
{
dup2(me->fd_in, 0);
me->fd_in > 0 ? close(me->fd_in) : 0;
if (!is_last)
dup2(pfd[1], 1);
else if (curs->parent->parent && curs->parent->parent->fd_out >= 0)
dup2(curs->parent->parent->fd_out, 1);
close(pfd[0]);
exec_mpipe(me, curs);
exit(-1);
}
else if (curs->pid > 0)
{
waitpid(curs->pid, &(curs->ret), WUNTRACED);
handle_pid(me, curs->ret);
close(pfd[1]);
me->fd_in = pfd[0];
}
return (pid >= 0 ? 1 : -1);
}
我希望有人能理解我在说什么,也许能帮上忙.. 谢谢
在等待 任何 个程序完成之前,您需要启动管道中的所有 个程序。
您的 shell 实现正在等待每个管道元素完成,然后再开始下一个。但是/dev/urandom
是源源不断的; cat /dev/urandom
会 运行 直到被杀死。所以第二个 cat
永远不会开始,直到你 control-C 第一个。