How to stop subprocesses from copying listening sockets

R

Rick van Hattem

Hi everyone,

Recently I've started building a program that spawns new processes when
requested via http, since the http interface doesn't need to be fancy I've
just used the BaseHTTPServer module for this, but... it seems I'm running
into a little problem. When spawning a new process (which forks itself into a
daemon, but isn't too relevant in this case) the listening socket is copied
to the new process. Evidently this results in the base process not being able
to restart since the new spawned process starts listening on the port.

Here's a simple example of what I mean.
Assuming we've got the server like this:
import subprocess
import BaseHTTPServer

server = BaseHTTPServer.HTTPServer(('', 1234),
BaseHTTPServer.BaseHTTPRequestHandler)

subprocess.Popen(['python', 'the_daemon.py'])


With the_daemon.py being this:
import time
time.sleep(60)

And we run the main server and kill it after that (i.e. using netstat to find
the PID), we'll see that the new process which does nothing besides wait for
60 second will listen on port 1234 (use netstat to confirm).

Anyone has an idea on how to circumvent this issue?

Kind regards,

Rick van Hattem

PS: tested both on Fedora 8 using Python 2.5.1 and Gentoo Linux 2008 using
Python 2.5.2
 
R

Roy Smith

Rick van Hattem said:
Recently I've started building a program that spawns new processes when
requested via http, since the http interface doesn't need to be fancy I've
just used the BaseHTTPServer module for this, but... it seems I'm running
into a little problem. When spawning a new process (which forks itself into a
daemon, but isn't too relevant in this case) the listening socket is copied
to the new process.

The standard solution to this problem is to close all descriptors after
forking and before doing the exec. You can tell subprocess.Popen() to do
this by call it with "close_fds=True".
 
R

Rick van Hattem

The standard solution to this problem is to close all descriptors after
forking and before doing the exec. You can tell subprocess.Popen() to do
this by call it with "close_fds=True".

Thank you very much, I completely forgot about the close_fds argument.

That will fix the problem nicely :)
 

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

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top