Subject: Re: Real vfork() (was: third results)
To: None <tech-kern@NetBSD.ORG>
From: Robert Elz <kre@munnari.OZ.AU>
List: tech-kern
Date: 04/15/1998 03:49:40
    Date:        Tue, 14 Apr 1998 10:03:03 -0700
    From:        Jason Thorpe <thorpej@nas.nasa.gov>
    Message-ID:  <199804141703.KAA14300@lestat.nas.nasa.gov>

  | ...because vfork() has always been defined to block the parent until
  | the child either (a) exits, or (b) execs.

That's a vfork() limitation - something that you need to be aware of
to use vfork(), it was never intended to be a feature that anyone could
rely upon, programs that don't work when compiled with -Dvfork=fork are
broken, pure and simple.

vfork() was, and generally still is, an ugly hack to decrease the cost
of fork() in the many cases that little needs to be done between fork() and
exec() (or exit()) such that it is possible to live with the limitations
that vfork() imposes.   While its nature permitted some real nasty stuff to
be done, use of anything at all that would defeat simple replacement of
vfork() by fork() was always a bug.   Of course, broken programs do exist.
Original csh at least was not one of them though, it used to compile and run
on systems without vfork() with no difficulty at all - whether that's still
true with all the hacks that have been done to it I don't know, but these
days there's little rationale for anyone to keep using csh variants any more
anyway, bash, and other shells, are much better.   csh was, of course, the
original user of vfork(), it was, comparatively, so big, that a regular fork()
make it much more expensive to run than sh - with csh using vfork() and
sh, naturally, still using fork(), csh seemed so much faster...

And while I am here, it is amusing to see the forkexec()/spawn()/... debate
taking place all over again.   It should hardly be a surprise that this is
not the first time.   Before any more time is wasted on that, someone should
go look at all the places they believe they could use such a sys call, real
code that is, not imagination, and see just what it would have to do to be
useful.   Every time that's been attempted before, whoever was doing it
realised quite quickly that the whole thing is beyond hope - the call would
either need a hundred args to specify everything that may need specifying in
some cases, or would be of such limited use that it simply isn't worth the
effort - don't you all think that if this would have been cleaner, it would
have been created rather than vfork() all those years ago?   The kernel part
of it (or at least, the base part, leaving aside all the options that would
be needed) is trivial.

All that is really needed is to look at libc() and see that there's no
library function which does the combined job (except system(3) and popen(3)
which are much more highly specified to particular tasks).   If a combined
fork()/exec() was going to be really useful, you would have found it at least
creaping into libc by now, implemented in terms of [v]fork() and exec*().
If anyone really wants to experiment with this, that's where you should start,
just make a libc function that does what you think should be done, and modify
a bunch of programs (or write new ones if that's how you see it catching on)
to use the library routine, and see how well you go.

kre