[Toybox] vfork() deprecated on macOS

Rob Landley rob at landley.net
Sat May 14 06:03:59 PDT 2022


On 5/11/22 15:20, enh via Toybox wrote:
> the toybox build is pretty noisy on a current mac, complaining that
> vfork() should be replaced by fork() or posix_spawn().

Sigh.

> looks like it's because they've changed vfork() to just be fork() and
> would like people to accept that they understand that by changing
> their source to say fork() instead... (i'll copy & paste the man page
> here because afaik apple doesn't give us anywhere to link to...)

I.E. mac will never work on a nommu system. Got it.

>      The vfork system call can be used to create new processes. As of macOS
>      12.0, this system call behaves identically to the fork(2) system call,
>      except without calling any handlers registered with pthread_atfork(2).

That's very much not what it's for. Apple hasn't got anybody left there who
understands why it was there in the first place.

(There are more nommu processors in the world than there are mmu processors.
It's sort of a "total weight of all insects" vs "total weight of all mammals"
thing. You just don't _notice_ them...)

>      This system call is deprecated. In a future release, it may begin to return
>      errors in all cases, or may be removed entirely.  It is extremely strongly
>      recommended to replace all uses with fork(2) or, ideally, posix_spawn(3).
> 
> weirdly it looks like you can use _POSIX_C_SOURCE to make this go
> away? from their unistd.h:
> 
> #if !defined(_POSIX_C_SOURCE)
> __deprecated_msg("Use posix_spawn or fork")
> #endif
> pid_t    vfork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;

We can move that header into portability.h if we need to? It's #included before
the rest for a reason...

> -Wno-deprecated-declarations in configure works too,

I'm happy to wait for it to break and then fix it better then. :)

> though their
> threat to make vfork() always fail in a future release makes me
> question whether that's such a good idea. (i haven't followed apple
> closely enough to know whether there's any precedent for violent
> breakage like that. i'm not sure why you wouldn't just remove the
> symbol rather than replace it with an implementation that always
> fails?)

Ask Rich Felker with his insistence that fork() must always be there on nommu
systems and return -EINVAL, and me patching it out with an #ifdef in my build
script.

Rob

P.S. A few years ago I did a contract at a place that ported an old system from
wince to Linux and ran an ~80-thread .net app under mono, and every time they
forked from one of those threads it froze the whole app for 75 miliseconds while
it copied all of its memory to the new process. (Because forking from a thread
defeats copy on write, the kernel doesn't even TRY to track it and just copies
everything, which involves locks.) Unfortunately something needed 4ms response
time to avoid going "boing". The fix was to replace the fork() with a vfork()
which only froze the ONE thread that called it (until it could do the rest of
its setup and _exit() or exec() the new process). No big memory copy, thus no
latency spike. On a system that had an MMU, and yet...



More information about the Toybox mailing list