the dreaded double fork

John Hunter jdhunter at ace.bsd.uchicago.edu
Wed May 5 11:14:05 EDT 2004


I am using python to run an xml rpc daemon using SimpleXMLRPCServer.
Following a cookbook recipe, I am trying to do a double fork so that
when I exit the shell the daemon remains running.  But it doesn't.
Here is how I start the script

> ssh somehost
> sudo python mydaemon start&

But when I exit the shell, I lose the process.

What am I doing wrong?  Here is my script, with all the non server
stuff snipped.

import sys, os 


pidfile = '/tmp/ogtt_daemon.pid'
host = 'dardd.bsd.uchicago.edu'
port = 2358


class AnalysisServer: 
    snip

def main():
    import SimpleXMLRPCServer

    while 1:
        # Daemon's main code goes here                
        server = SimpleXMLRPCServer.SimpleXMLRPCServer((host, port))
        server.register_instance(AnalysisServer())
        server.serve_forever()


def get_daemon_pid():
    if os.path.exists(pidfile):
        pid = open(pidfile, 'r').read()
        return int(pid)

    else:
        return None

def stopd():
    print 'Stopping daemon...',
    if not os.path.exists(pidfile):
        print 'Daemon does not appear to be running'
        return
    pid = get_daemon_pid()
    os.popen('kill -9 %d' % pid)
    print 'OK'
    os.remove(pidfile)

if __name__ == "__main__":

    if sys.argv[1]=='start' and os.path.exists(pidfile):
        print 'Process appears to be running'
        sys.exit()
        
    if sys.argv[1]=='stop':
        stopd()
        sys.exit()
        
    # do the UNIX double-fork magic, see Stevens' "Advanced 
    # Programming in the UNIX Environment" for details (ISBN 0201563177)
    try: 
        pid = os.fork() 
        if pid > 0:
            # exit first parent
            sys.exit(0) 
    except OSError, e: 
        print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) 
        sys.exit(1)

    # decouple from parent environment
    os.chdir("/") 
    os.setsid() 
    os.umask(0) 

    # do second fork
    try: 
        pid = os.fork() 
        if pid > 0:
            # exit from second parent, print eventual PID before
            print "Daemon PID %d" % pid 
            file(pidfile, 'w').write('%d\n'%pid)
            sys.exit(0) 
    except OSError, e: 
        print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) 
        sys.exit(1) 

    # start the daemon main loop
    main() 






More information about the Python-list mailing list