passing a socket to a spawned process.

M

Mike M

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!!

Mike
 
M

Marcos Dione

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?

just accept() before fork()'ing. the socket will be cloned. then close the
socket on the parent, unless needed.

--
(Not so) Random fortune:
(Really) Random fortune:
mdione@tempest:~$ cat /dev/random | uuencode random | head -n 3
begin 644 random
M=?:,8:mad:5MVVIM6>NAYQ6O@I&H86>.3(L"F7S>U'.9`2;%LEAR/E8M[*F=(MP
M5C>B3Y2F(X,`SW1UPAL*+OIV'EM/Z$_-15':B#<6I99_P,H%=$S6$H<&W-!;
 
J

Josiah Carlson

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
 
A

Alex Martelli

Marcos Dione said:
just accept() before fork()'ing. the socket will be cloned. then close the
socket on the parent, unless needed.

Unfortunately I believe that's platform-dependent. Specifically: your
suggestion should work on any sensible operating system... BUT a tad
over 50% of Python programs are estimated to run on Windows, and, on
THAT platform, I know your idea can't work (no fork!) and I don't know
how to answer the OP's question (except by suggesting he move, if
feasible, to any sensible platform -- any BUT Wind0ws...!-).


Alex
 
A

Andrew MacIntyre

Unfortunately I believe that's platform-dependent. Specifically: your
suggestion should work on any sensible operating system... BUT a tad
over 50% of Python programs are estimated to run on Windows, and, on
THAT platform, I know your idea can't work (no fork!) and I don't know
how to answer the OP's question (except by suggesting he move, if
feasible, to any sensible platform -- any BUT Wind0ws...!-).

I've not tried this on Windows, but on OS/2 using the native sockets
(which is close to the Windows socket model as far as I can tell) you have
to pass the socket handle (an integer) to the child (usually via the
command line), which then attaches to the socket, and signals the parent
that it can close its reference to the socket.

The EMX (OS/2, Win32) and Cygwin (Win32) runtime environments synthesize
fork() and socket inheritance over the native environment, though at a
significant cost in run time and resources.
 
M

Michael Loritsch

Josiah Carlson said:
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
 
J

Josiah Carlson

On 16 Oct 2004 00:32:23 -0700
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
 
M

Martin Atkins

I recently wrote a c module for Python, for passing file descriptors and process
credentials down unix domain sockets under Linux. (using sendmsg(2))

It was pretty easy, and I could send it to anyone interested. Contact me
off-list, since I don't normally read this group.

Perhaps there is a need for a OS-independant wrapper around versions
specifically for Linux, Windows, Solaris, etc?

Martin
 
J

Josiah Carlson

I recently wrote a c module for Python, for passing file descriptors and process
credentials down unix domain sockets under Linux. (using sendmsg(2))

It was pretty easy, and I could send it to anyone interested. Contact me
off-list, since I don't normally read this group.

Perhaps there is a need for a OS-independant wrapper around versions
specifically for Linux, Windows, Solaris, etc?

Martin

I'll take the source for the C version. And in general, yes, Python
could use such a thing for all platforms, though I'm not sure all
platforms support it.

- Josiah
 
D

Donn Cave

Josiah Carlson said:
I'll take the source for the C version. And in general, yes, Python
could use such a thing for all platforms, though I'm not sure all
platforms support it.

Rest assured, not all platforms support it.

Donn Cave, (e-mail address removed)
 
M

Martin C.Atkins

I have (finally!) put a package up on our website that provides a
Python module for sending file descriptors down Unix-domain sockets, on Linux.

See the first item under:
http://www.mca-ltd.com/index.php?PAGE=resources/home.php

Please let me know of any problems, obvious omissions, etc...

BTW: I just found out about bindd (see the README), and could probably
clean the code up from the examples in its sourcecode, but the current
version of fdcred works for me!

Sorry it has taken so long!

Regards,
Martin
 
D

Dave Cole

Martin said:
I have (finally!) put a package up on our website that provides a
Python module for sending file descriptors down Unix-domain sockets, on Linux.

See the first item under:
http://www.mca-ltd.com/index.php?PAGE=resources/home.php

Please let me know of any problems, obvious omissions, etc...

BTW: I just found out about bindd (see the README), and could probably
clean the code up from the examples in its sourcecode, but the current
version of fdcred works for me!

Sorry it has taken so long!

I notice that you have used the LGPL for your code. Could you be
convinced to use a Python style license?

This would mean that some time in the (hopefully not too distant) future
the code could be added to the standard socket module.

- Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top