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>