2 ms·
> the kernel has an easier time of single-handedly cleaning up all file descriptors, memory mappings, etc. in one fell swoop inside execve() fork() / execve()
by xenadu02 8y ago
> the kernel has an easier time of single-handedly cleaning up all file descriptors, memory mappings, etc. in one fell swoop inside execve()
fork() / execve() isn't a good mechanism for launching new processes; it's one of the worst aspects of early Unix design.
A properly designed syscall should require the caller to specify the desired behavior explicitly:
1. Do I want to inherit file descriptors, etc or do I want a clean slate?
2. Do I want a separate address space or to share address space?
3. What happens to threads, mutexes, locks, etc in the new child process?
4. If a separate address space should I inherit my parent's VM mappings or should I just load and execute a new binary image?
That gives flexibility to the caller and maximum information to the kernel to optimize. Instead we have a bunch of ad-hoc patches like vfork(), clone(), and posix_spawn() (+ non-standard attributes like POSIX_SPAWN_CLOEXEC_DEFAULT, POSIX_SPAWN_SETEXEC, and POSIX_SPAWN_USEVFORK).