TCdrone
TCdrone

Reputation: 3

Forked child "prints" redirected stdout twice

Inside a while(1) I'm trying to:

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

Answers (1)

Chris Dodd
Chris Dodd

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

Related Questions