Reputation: 3
Inside a while(1) I'm trying to:
spawn a child process with fork();
redirect the child process stdout so that the parent process can see it
print the result in the terminal from the parent process
repeat
Strangely, the output from the child process seems to be printed twice
// parentToChild and childToParent are the pipes I'm using
while(1) {
int pid = fork();
if(pid < 0) {
// error, get out
exit(0);
} else if(pid != 0) {
// parent process
close(parentToChild[0]); // don't need read end of parentToChild
close(childToParent[1]); // don't need write end of childToParent
sleep(4);
char respBuffer[400];
int respBufferLength = read(childToParent[0], respBuffer, sizeof(respBuffer));
printf("before\n");
printf("parent tried to read something from its child and got: %s\n", respBuffer);
printf("after\n");
} else if (pid == 0) {
if(dup2(childToParent[1], STDOUT_FILENO) < 0) {
// printf("dup2 error");
};
close(childToParent[1]);
close(childToParent[0]);
close(parentToChild[1]); // write end of parentToChild not used
printf("child message");
// if we don't exit here, we run the risk of repeatedly creating more processes in a loop
exit(0);
}
}
I would expect the ouput of the following loop at each iteration to be:
before
parent tried to read something from its child and got: child message
after
But instead, at each iteration I get:
before
parent tried to read something from its child and got: child message
after
child message
What's the reason behind the second print of "child message"?
Flushing the stdout buffers before calling fork() doesn't seem to solve the issue
Interestingly, removing the while loop and keeping everything else intact seems to work fine
Upvotes: 0
Views: 437
Reputation: 126223
In the first iteration of the loop, you close childToParent[1]
in the parent, and you don't recreate the pipes, so in the second iteration of the loop, its trying to reuse those closed pipes, so the child's dup2
call fails, so its printf goes to the terminal. Meanwhile, in the parent, the read
call returns 0 without writing anything to the buffer, so you just print the old contents.
Upvotes: 1