As vfork creates the child process in the same address space as that of the parent, and when execv() is called on the child then how is the parent process restored, as exec loads the file and runs it in the same address space of the parent and hence the child?
Advertisement
Answer
When execv
follows a true vfork
, it does some of the work of fork
: it allocates a new memory space into which to load the new program image and copies inheritable things like environment variables into it. Meanwhile, even vfork
saves a bit of the parent’s state on the side, so that execv
can restore the parent’s stack and instruction pointers once the child is separated.
For example, on Linux vfork
calls common process-copying code via _do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, ...)
. copy_mm
reacts to the CLONE_VM
and just reuses the memory space with no call to dup_mm
. _do_fork
meanwhile reacts to the CLONE_VFORK
, marks the child vfork_done
, and suspends the caller until the memory space is no longer in use; if this is via execve
, it goes through exec_mmap
and mm_release
, which sees the vfork_done
and wakes the parent.
So, really, execve
(which also calls copy_strings
) is always “allocating a new memory space and copying environment variables into it”; after a normal fork
, however, this is not observable because it happens at the same time as releasing the non-shared space created by the fork
.