This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: posix_spawn's usage of fork versus vfork
On Wed, Oct 6, 2010 at 11:37 PM, Mike Axiak <mike@axiak.net> wrote:
> Surely other people have hit this particular issue before? I hope that
> I am missing an obvious feature of one of these functions, and that
> someone can just point me in the right direction. Should I just be
> content with (1) as my solution? Should I even try (2)?
If you call vfork the standard says you may only use exec* family
functions next.
In practice on Linux the child must not:
* modify any global variables
* modify any local variables visible to the parent
In practice the child can get away with:
* call functions, since pushing new data on the stack does not affect the parent
* open or close files, since the parent and child do not share file
descriptors, as CLONE_FILES is not passed as a flag to do_fork
* make system calls that do not affect global memory
It is an optimization that GLIBC uses vfork() in some cases where
there is zero work to be done before the exec*.
Given the above practical constraints it might be possible to augment
posix_spawn to use vfork in more cases.
At present this is the set of conditions that controls vfork vs. fork:
libc/sysdeps/posix/spawni.c
~~~
/* Generate the new process. */
if ((flags & POSIX_SPAWN_USEVFORK) != 0
/* If no major work is done, allow using vfork. Note that we
might perform the path searching. But this would be done by
a call to execvp(), too, and such a call must be OK according
to POSIX. */
|| ((flags & (POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF
| POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER
| POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_RESETIDS)) == 0
&& file_actions == NULL))
new_pid = __vfork ();
else
new_pid = __fork ();
~~~
Hopefully that explains why GLIBC doesn't use vfork if you have file actions.
You need to either solution #1 or #2. Most people probably do #2 to
reduce the penalty of the exec*.
Cheers,
Carlos.