passing a socket to a spawned process.
Josiah Carlson
jcarlson at uci.edu
Sat Oct 16 04:20:38 EDT 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