[英]fork/pipe/dup2 issue: child process never exits
I want to write a small program that prints out a long list which can be paged in the terminal through more
(or less
) so that the list can be examined from head to toe... 我想写一个小程序,打印出一个长列表,可以通过
more
(或less
)在终端中进行分页 ,以便可以从头到脚检查该列表...
The program: 该程序:
fork
's off a child process in which the more
program is executed fork
出执行more
程序的子进程 pipe
set up between parent/child so that the list printed to stdout
by the parent is sent to the more
program's stdin
pipe
,以便将由父打印到stdout
的列表发送到more
程序的stdin
code: 码:
int main(int argc, char *argv[])
{
int pager, status;
int pipes[2];
pipe(pipes);
pager = fork();
if (pager == 0) { // child
dup2(pipes[0], 0);
close(pipes[1]);
char *args[] = {"more", NULL};
execvp(args[0], args);
} else { // parent
dup2(pipes[1], 1);
int x;
for (x = 0; x < 500; x++) {
printf("Hello World! %d\n", x);
}
close(pipes[0]);
close(pipes[1]);
wait(&status);
}
return 0;
}
I have this working for the most part: 我大部分工作是这样的:
--More--
so I know the basic pipe setup is working. --More--
剪裁,因此我知道基本的管道设置正在工作。 [q]
before the entire list finishes printing (quit the more
process) the programs (parent/child) exit as expected more
过程)之前按[q]
,程序(父/子)将按预期退出 The only problem I am having is that if I keep pressing [space]
or [return]
(which advances the output given by more
) and reach the end of my list (the 500th "Hello World!..." message) then the terminal just hangs. 我唯一的问题是,如果我继续按
[space]
或[return]
(这将使more
的输出前进)并到达列表的末尾(第500个“ Hello World!...”消息),则终端只是挂起。 Pressing [q]
is unresponsive (I have to [ctrl+c]
to get out). 按
[q]
无响应(我必须按[ctrl+c]
才能退出)。
The parent process is stuck on wait
. 父进程处于
wait
。 The more
process is not exiting even though I have closed both pipes in the parent 即使我已经关闭了父管道中的两个管道,也没有退出
more
过程
In your code you are closing pipe[0]
which is not the descriptor you are writing to the child. 在您的代码中,您正在关闭
pipe[0]
,这不是您要写入子代的描述符。 You did a dup2(pipes[1], 1)
so in order to tell the child that the pipe has ended you must close the one you are writing to. 您做了一个
dup2(pipes[1], 1)
所以为了告诉孩子该管道已经结束,您必须关闭正在写入的那个。
close(1);
Of course you'd have to restore the original output if you intend to continue your process using stdout, as this would be closed now. 当然,如果您打算使用stdout继续执行过程,则必须恢复原始输出,因为现在将关闭该输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.