Fork rule #1: After a successful fork, execution in both the parent and child process continues at the instruction following the fork.
Why does it happen this way? Well, think about it: the job of fork is to make a (pretty much) identical copy of the parent in the child; this includes the hardware context (mentioned earlier), which of course includes the Instruction Pointer (IP) register (sometimes called the Program Counter (PC)) itself! Hence, the child process too will execute the user mode code at the same location as the parent. As the fork is successful, control will not go the error handling code (the FATAL() macro); instead, it will go to the printf . The key point is this: this will happen in both the (original) parent and the (new) child process. Hence the output.
To reinforce the point, we write a third version of this same simple C program (ch10/fork3.c). Here, we just show the printf statement as it's the only line of code that changes (from the ch10/fork3.c):
printf("PID %d: Hello, fork. ", getpid());
Build and run it:
$ ./fork3
PID 25496: Hello, fork.
PID 25497: Hello, fork.
$
Ah! Now we can actually see that two processes have run the printf! Probably (but not for sure), PID 25496 is the parent process, the other of course is the child. After this, both processes execute the exit(3) API, and thus both die.