Passing TCP socket descriptors around
In linux, normally, it is impossible to "bind()" to the same TCP port twice. If you try to bind to the same port from second proces unix processes you'll see:
socket.error: [Errno 98] Address already in use
It is possible on UDP, using SO_REUSEPORT option, but that's separate story.
There are two possible ways to pass a socket to a different process without interruption.
If you can sustain interruption - just "close" the socket in one process and "bind" in another one.
This is what haproxy appears to be doing:
http://comments.gmane.org/gmane.comp.web.haproxy/7815 During the process switch, nobody is listening anymore, for a very short time: the old process must release the listening port to let the new one bind a new socket on it.
After a parent does fork(), in linux, both parent and child may do "accept" and receive a connection. When doing blocking "accept" syscall, the incoming connections will be spread in round-robin fashion, for example (see fork_server.py):
connection got in parent from ('127.0.0.1', 48306) connection got in child from ('127.0.0.1', 48308) connection got in parent from ('127.0.0.1', 48310) connection got in child from ('127.0.0.1', 48312) connection got in parent from ('127.0.0.1', 48314)
Sendmsg and Recvmsg syscalls can be used to pass file descriptor over a unix socket. See "man cmsg" and "man 7 unix" under "Ancillary Messages" sections.
The API is not well documented, but that's for example what node.js (actually libuv) uses:
This must be passed over unix socket. I'm not really sure how that works internally in the kernel.