[PATCH] dropbear-051: uClinux vfork

Jamie Lokier jamie at shareable.org
Thu Oct 23 18:12:03 WST 2008


Rob Landley wrote:
> On Tuesday 21 October 2008 00:01:56 Mike Frysinger wrote:
> > -	if ((pid = fork()) == -1)
> > +#ifdef __uClinux__
> > +	pid = vfork();
> > +#else
> > +	pid = fork();
> > +#endif /* __uClinux__ */
> > +	if (pid == -1)
> >  		fatal("do_local_cmd: fork: %s", strerror(errno));
> 
> If it's ever safe to call vfork() from a given place, then it should
> always be safe to call it from that place, so the #ifdef isn't
> really necessary.

Not always true.  This is true if you're following the portable rules
for what a vfork-child can do, or if you expect the code to only run
on Linux.

On uClinux (and Linux), a vfork-child can get away with quite a lot of
things that are not safe on other OSes.  For example, malloc() and
printf() are probably fine, because they update memory in the same way
as the parent would anyway.  Thread-local storage keys off the stack
address, if you're using LinuxThreads not NPTL, so again the
vfork-child updates memory the same way as the parent.  Setting signal
handlers or masks in the vfork-child are fine and don't affect the
parent in Linux, same for chdir().  execvp() is ok, even though that
calls malloc() (in at least one Glibc version I looked at).

In my own library of portable code, I use vfork() on OSes where either
the child is following the very restrictive rules, or it's uClinux and
there's no choice and it'll work when the child doesn't follow all the
rules.  I don't use vfork() for daemon() though, as that doesn't work
(I've seen some uClinux patches do that and it's just broken); clone()
works for that.  I get nervous when it's uClinux _and_ threaded. :-)

-- Jamie



More information about the Dropbear mailing list