Daniel B. answered 10/11/22
PhD in Computer Science with 42 years in Computer Research
Question: But what is happening to the grandchild?
Answer:
The grandchild replaces itself with the cp command, which eventually terminates.
That is why the grandchild does not become a zombie.
Question: How come the parent is not blocked?
Answer:
The parent waits for the child, not the grandchild.
And the child exits unconditionally as soon as it spawns the grandchild.
(The last thing may not be obvious because the indentation is confusing --
the "exit(0)" statement is in the child's code, not the grandchild's code.)