Since stdout is used for control and for data, add a new message type
(proxy) to distinguish them.
When a child calls exec():
* if the call is unsuccessful, the child writes a term to stdout which
the parent proxies
* if the call is successful, no value is returned but the child will close
the control socket on exec. The parent will "spoof" an "ok" response.
Allocate the message headers on the heap to make it easier to layer them.
If the child process has not exec'ed, use the packet length to avoid
having multiple writes coalesce into a single read.
Before checking if an fd is ready, ensure the fd is a positive value. On
freebsd, invalid fd's cause FD_ISSET() to segfault.
Modify the message format to include the PID. Tests pass but requires
much more work. The message format is now:
* erlang -> port: make a call
2:ALCOVE_MSG_CALL
2:call
*:arg
* port -> erlang: call results
2:ALCOVE_MSG_CALL
*:arg
* erlang -> port: write to child's stdin
2:ALCOVE_MSG_CHILDIN
4:pid
* port -> erlang: write from child's stdout
2:ALCOVE_MSG_CHILDOUT
4:pid
*:data
* port -> erlang: write from child's stderr
2:ALCOVE_MSG_CHILDERR
4:pid
*:data
alcove acts a proxy between the Erlang VM and a forked process. It can
enforce restrictions on the child process, such as dropping privileges,
setting resource limits and chroot'ing.
The goal is to support Linux namespaces, seccomp mode and cgroups so
the port process can run in an application container.
alcove should be portable though and a subset of the features should
work on any unix, possibly even supporting the sandboxing mechanisms on
other platforms.