joyent/libuv — pull request #322 by AvianFlu (2012-02-23 22:23:17+00:00)
Title: Add 'detached' option for child processes

This introduces a new `detached` option in `uv_process_options_t`, which denotes that a given child process should be spawned in a 'detached' state. Put simply, the child will be run in the background, without a connection to the parent, and without any controlling tty.

### Unix

On unix, the best way to achieve this was by adding a second `fork(2)` - in this implementation, there is a short-lived 'first child', which makes a call to `setsid()` before forking again.
This ensures two things:

- The second child will be a session/process group leader.
- The original parent is under no obligation to stay running after detaching the child.

To make sure that `process->pid` refers correctly to the detached child and not the intermediate child, `mmap()` is used to create a small amount of shared memory (`sizeof(pid_t)`) between the forks. The first child saves the second child's pid to this map, and then the map is removed after `process->pid` is set in the parent.

### Windows

The Windows implementation was mostly a matter of finding the right combination of flags for `CreateProcessW()`. `CREATE_NO_WINDOW`, `CREATE_NEW_PROCESS_GROUP`, and `DETACHED_PROCESS` were all necessary to produce the same functionality as unix.

It was also necessary to set the timeout value on `RegisterWaitForSingleObject()` to 0 when `options.detached` is set. The timeout without `detached` set is `INFINITE` - i.e. keep waiting until the child exits - but a timeout of 0 simply checks for a successful start and then calls the exit callback.

On both platforms, the parent treats the child as if it exited successfully, and no stdio handles are preserved.