I have the main process forking two times and thus creating two children. The two children are piped with each other like this:
ls | more
Now the problem is that the second child never dies. Why is that? When does the last child in a pipe die really?
Removing one wait() call shows the expected result of ls | more
but gives some further weird behaviours(stuck terminal etc).
Here is my code:
int main(){
printf("[%d] main\n", getpid());
int pip[2], i;
pipe(pip);
/* CHILDREN*/
for (i=0; i<2; i++){
if (fork()==0){
/* First child */
if (i==0){
printf("[%d] child1\n", getpid());
close(1); dup(pip[1]);
close(pip[0]);
execlp("ls", "ls", NULL);}
/* Second child */
if (i==1){
printf("[%d] child2\n", getpid());
close(0); dup(pip[0]);
close(pip[1]);
execlp("more", "more", NULL);}
}
}
wait(NULL); // wait for first child
wait(NULL); // wait for second child
return 0;
}
Check with
ps axw
that it's really themore
that isn't dying. Then read the man page for wait. Look at the returned status forwait
.(Hint: look at what causes a 'zombie' process. I don't think the waits are doing what you think they are.)
The read end of the pipe won't get an EOF mark until the write end has been closed by all its users. The parent of both children still has both ends of the pipe open, so
more
doesn't see an EOF (a return of 0 fromread()
), and keeps waiting for more input.