Search code examples
cprocesswaitpid

Waiting process to return


Consider:

int main()
{
        if (fork() == 0){
            printf("a");
        }
        else{
            printf("b");
            waitpid(-1, NULL, 0);
        }
        printf("c");
        exit(0);
 }

(from Computer Systems, Bryant - O'Hallaron).

We are asked for all the possible output sequences.

I answered: acbc, abcc, bacc. However, I am missing one output compared to the solution (bcac). I thought this output was not possible because the parent process waits for its child to return before printing c (waitpid). Is this not true? Why? And, in that case, what is the difference between the code above and the same without the waitpid line?


Solution

  • I don't see any way bcac is possible. At first I expected some trickery based on the stdio buffers being flushed in an unexpected order. But even then:

    The child won't output c until after it has output a. Therefore the first c in bcac must have come from the parent.

    The parent won't output c until after the waitpid completes. But that can't happen until after the child is finished, including the final stdio flush that happens during exit(). Therefore the first c is always from the child.

    Proof by contradiction has been achieved... the output can't be bcac.

    Well, there is one thing you could do to mess up the order. You could exec the program inside a process that already has a child which is about to exit. If the pre-existing child exits before the new child prints a, then the main process will detect that exit with waitpid, and go ahead and print its stuff and possibly exit before the child prints anything.

    This is something to watch out for in setuid programs: don't assume that because your program only created one child process that it only has one child process. If you're in an advanced defensive-code learning context this answer makes sense. In a unix-newbie context it doesn't seem relevant, and it's probably better to just say bcac is impossible, even though it's technically not true.