passing a socket to a spawned process.

Josiah Carlson jcarlson at uci.edu
Sat Oct 16 10:20:38 CEST 2004


On 16 Oct 2004 00:32:23 -0700
loritsch at gmail.com (Michael Loritsch) wrote:

> Josiah Carlson <jcarlson at uci.edu> wrote in message news:<mailman.4761.1097598633.5135.python-list at python.org>...
> > > Is it possible?  In the parent process, I have a socket that binds,
> > > listens and then accepts new connections (which creates new sockets in
> > > the process).  I want to be able to pass some of these new sockets to
> > > a spawned process.  Is it possible, and if so how?
> > > 
> > > Any help is much appreciated!!
> > 
> > As someone has already mentioned, if you have the socket before the fork,
> > you will have the socket after the fork.
> > 
> > 
> > I had been working on a general file descriptor passing mechanism for a
> > few weeks in May, until I gave up.
> > 
> > From what I was able to work out, it is not possible in Windows.
> > SunOS 5.8 has no issues, and will work almost out of the box (pure
> > Python) with the right incantation (I have it somewhere if you really
> > want it).
> > A few constants are missing from the Linux fcntl.py, so this is not
> > really possible unless you are willing to patch your kernel and Python.
> > 
> > Googling for the terms: passing file descriptors Python
> > will get you the list of articles/research that I looked at.
> > 
> > One of those links has source code for the C struct usable with a BSD
> > for making this happen.  Generally though, you can only pass file
> > descriptors (sockets) across a UNIX domain socket, or sometimes a pipe
> > (make it before you fork).
> > 
> > 
> > Good luck.
> >  - Josiah
> 
> 
> Passing sockets to spawned processes is also possible in Windows, but
> tricky.
> 
> While I have never passed a socket between python processes, I have
> passed a socket handle from a python process to a Windows binary. 
> Using the win32api extensions packaged with the ActiveState
> distribution, one should be able to pass the socket between python
> processes just as well.
> 
> The basic pseudo-code for doing so is as follows:
> 
> Parent process:
> 1) Obtain socket connection in parent server process from a client
> process.
> 2) Obtain Windows process id -> use win32api.GetCurrentProcessId()
>    - This process id will later be sent to the child process.
> 3) Spawn child process, obtaining a pipe to child_stdin -> use one of
> the os.popen functions.
> 4) Using child_stdin pass parent process id (obtained in 2) to the
> child process.
> 5) Next, using child_stdin pass over the socket file id, using
> socket.fileno().
> 
> Now the child process should have everything it needs to listen on the
> socket.
> 
> Child process:
> 1) Read parent process id from stdin.
> 2) Read socket file id from stdin.
> 3) Obtain a handle to the parent process using the process id -> use
> win32api.OpenProcess().  This handle will be needed in the next
> call...
> 4) Turn your socket file id into a socket -> use
> win32api.DuplicateHandle().
>    - hSourceProcess is the handle obtained in 3
>    - hSource is the file id
> 
> You are now done, and should be able to read data on the socket in the
> child process!


Goodness, I guess it is possible in Windows.  That kind of thing is
really useful for a "pre-forked" server with multiple processes, or even
a super-daemon that listens on ports specified by other daemon processes
in order to handle automatic failover.

Looks like I have a reason to download pywin32 after all.

Now if only it could be done in linux out of the box.

 - Josiah




More information about the Python-list mailing list