When you call
vfork(), a new process is created and that new process borrows the process image of the parent process with the exception of the stack. The child process is given an own new stack star however does not allow to
return from the function that called
While the child is running, the parent process is blocked, as the child borrowed the address space of the parent.
Regardless of what you do, everything that just accesses the stack modifies only the private stack of the child. If you however modify global data, this modifies the common data and thus also affects the parent.
Things that modify global data are e.g.:
calling malloc() or free()
modifying signal settings
modifying variables that are not local to the function that called
Once you call
_exit() (important, never call
exit()), the child is terminated and control is given back to the parent.
If you call any function from the
exec*() family, a new address space is created with new program code, new data and a part of the stack from the parent (see below). Once this is ready, the child no longer borrows the address space from the child, but uses an own address space.
The control is given back to the parent, as it's address space is no longer in use by another process.
Important: On Linux, there is no real
vfork() implementation. Linux rather implements
vfork() based on the Copy on Write
fork() concept introduced by SunOS-4.0 in 1988. In order to make users believe that they use
vfork(), Linux just sets up shared data and suspends the parent while the child did not call
_exit() or one of the
Linux therefore does not benefit from the fact that a real
vfork() does not need to set up an address space description for the child in the kernel. This results in a
vfork() that is not faster than
fork(). On systems that implement a real
vfork(), it is typically 3x faster than
fork() and affects the performance of shells that use
ksh93, the recent
Bourne Shell and
The reason why you should never call
exit() from the
vfork()ed child is that
exit() flushes stdio in case there is unflushed data from the time before calling
vfork(). This could cause strange results.
posix_spawn() is implemented on top of
vfork() is not going to be removed from the OS. It has been mentioned that Linux does not use
For the the stack, there is few documentation, here is what the Solaris man page says:
The vfork() and vforkx() functions can normally be used the
same way as fork() and forkx(), respectively. The calling
procedure, however, should not return while running in the
child's context, since the eventual return from vfork() or
vforkx() in the parent would be to a stack frame that no
So the implementation may do whatever it likes. The Solaris implementation uses shared memory for the stack frame of the function calling
vfork(). No implementation grants access to older parts of the stack from the parent.