passing a socket to a spawned process.

Michael Loritsch loritsch at gmail.com
Sat Oct 16 09:32:23 CEST 2004


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!

Regards,

Michael Loritsch



More information about the Python-list mailing list