I've used a machine with a real vfork() before now. The parent would crash
if the child left the function that vfork() is called from.

vfork is designed for just one purpose, a cheap replacment for fork() for
when you're spawning a new process from a shell (like program). It must
be used in code something like this:

   if( !(pid=vfork()) )
   {
      close(pipes[fd]);
      close(!fd);
      dup(pipes[!fd]);
      close(pipes[!fd]);
      /* Or something similar */

      exec(...);
      _exit(255);
   }

To quote a manual:
      The  use of vfork() for any purpose except as a prelude to
      an immediate exec() or exit() is not supported.  Any  pro�
      gram  that  relies upon the differences between fork() and
      vfork() is not portable across UNIX systems.

Also:
       vfork()  can  normally  be used just like fork().  It does
       not work, however, to return while running in the  child's
       context  from the procedure which called vfork() since the
       eventual return from vfork() would then  return  to  a  no
       longer  existent  stack  frame.  Be careful, also, to call
       _exit() rather than exit() if  you  cannot  exec(),  since
       exit()  flushes  and closes standard I/O channels, thereby
       damaging the parent process's  standard  I/O  data  struc�
       tures.  (Even with fork() it is wrong to call exit() since
       buffered data would then be flushed twice.)

The manual also notes that calling signal(2) can have weird effects!


The kernel implementation is not too difficult as the vfork() code in the
library is just:

_vfork:
  mov   ax,#32
  int   $80
  test  ax,ax
  jge  syscall_ok
  neg   ax
  mov   [_errno],ax
  mov   ax,#-1
syscall_ok:
  ret

This means that all you need to save is the stack pointer and the return
address for the last RET. The sp is already saved and the return address
can be saved somewhere else in *(current) ... say in BX, I imagine you 
need AX for the child PID. 

One other thing I noticed is that you trash the es register, the C library
treats this as callee saves, like si & di, but if I do that round every
int $80 it'll go an defeat this vfork() thing :-)

Putting a copy of the stack in the 'free space' is a _very_ bad idea,
it's sure to get overwritten sometime.

An interesting point is that you can nearly do this in userspace, but
unfortunatly the file descriptor semantics will bite you.

-- 
Rob.                          (Robert de Bath <http://poboxes.com/rdebath>)
                    <rdebath @ poboxes.com> <http://www.cix.co.uk/~mayday>

Reply via email to