Spawn is a small library exposing only one functionality: spawning sub-process.
It has three main goals:
provide missing features of Unix.create_process such as providing a working directory
provide better errors when a system call fails in the sub-process. For instance if a command is not found, you get a proper [Unix.Unix_error] exception
improve performance by using vfork when available. It is often claimed that nowadays fork is as fast as vfork, however in practice fork takes time proportional to the process memory while vfork is constant time. In application using a lot of memory, vfork can be thousands of times faster than fork.
Published: 19 Apr 2022
SPAWN - spawning system process
Spawn is a small library exposing only one function:
Spawn.spawn. Its purpose is to start command in the background. Spawn aims to provide a few missing features of
Unix.create_process such as providing a working directory as well as improving error reporting and performance.
Errors such as directory or program not found are properly reported as
Unix.Unix_error exceptions, on both Unix and Windows.
On Unix, Spawn uses
vfork by default as it is often a lot faster than fork. There is a benchmark comparing
spawn-lib/bench. If you don't trust
vfork, you can set the environment variable
SPAWN_USE_FORK to make Spawn use
Spawn is expected to be fully portable. However, so far it has only been tested on Linux, OSX and Windows.
Spawn.spawn simply uses the CreateProcess Windows function.
Under Linux, it uses a custom implementation that relies on
vfork followed by
execve. Compared to other implementations such as
Unix.create_process or the posix_spawn C library call, our implementations supports the following:
setting the current working directory of the child process
reporting errors from
execveto the caller
execve errors, our implementation proceeds as follow: just before calling
vfork we create a pipe with the
O_CLOEXEC flag. After forking, the parent reads from this pipe. If the
execve succeeds, the pipe get closed, the
read in the parent returns 0 bytes and the parent concludes that the
execve succceeded. If the
execve fails, the child process sends the error code to the parent via the pipe and exits.