Note that I can't seem to get the tests running locally, so I haven't been able to properly verify this!
It appears that Android plans to support posix_spawn in P release:
This code needs to work in M, at least.
Sorry I did not notice this before. Try vfork?
Simply using vfork instead of fork is probably a no-go: the vfork's man page (on macOS, I haven't verified the panoply of other BSDs) says that EINVAL is returned when "A system call other than _exit() or execve() (or libc functions that make no system calls other than those) is called following calling a vfork() call." That is, on platforms with this constraint using vfork where we currently use fork will fail, because we use other syscalls to do things like setup the file descriptor table.
- One option would be to simply use vfork on Linux only (where it does not have this restriction), and fork on all other platforms; this probably has the smallest diff.
- Another option would be to use posix_spawn on every platform except Android older than P and retain the existing fork-based implementation for them; this has a larger diff, but maybe in some glorious future we can delete the fall-back implementation for Android and end up with less code. This also let's us avoid calling vfork directly, which I have confidence is safe here, but which nonetheless has relatively fiddly semantics.
Do you have a preference between these two?
Really? Is that actually the case in practice, or is the man page too cautious? Cloning file descriptor tables should not make vfork any more expensive, and without that it is kinda useless. That's a pity.
I'd prefer to go with the smallest diff for now.
I've talked to our runtime and kernel folks and we should not be using vfork on Darwin. Even when the behavior you tested seems to work today, it might break tomorrow. Please opt out Darwin from vfork.
Also, it seems best to use posix_spawn wherever it's available. If Android doesn't have it, we should only fallback to fork/vfork on Android.
As a suggestion (perhaps for a future patch, not required to fix now): Could we detect the Android version at runtime and call posix_spawn on newer Android versions (where we know it's available)?
- Simply use vfork everywhere, the macOS manpage does not describe it's semantics correctly.
- Query for sysconf open max before vforking
- Switch back to using posix_spawn everywhere but Android
- Use posix_spawn based implementation on r28+ for Android
- Destroy file_actions
These are pointers to opaque structs, aka void *.
NDK packs a single asan library built for the lowest supported API level. It will basically never reach 28.
On the other hand, no one else has complained about fork() so far.
Tests hang with this change when output is redirected to a pipe. The test binary exits OK, but it looks like the process on the receiving end never gets an EOF.
Sorry, I don't have time to think about this now.
Please learn how to run tests and debug this.