Python: Tips For Writing Daemons

Here’s some useful information for writing daemons in Python.

One common problem that people run into is os.fork() producing zombie processes when children quit. This can easily be overcome by setting the SIGCHLD signal to SIG_IGN. ie:

import signal

signal.signal(signal.SIGCHLD, signal.SIG_IGN)

On some flavors of Unix, you are forced to do a double-fork on startup, in order to go into daemon mode. This is because single forking isn’t guaranteed to detach from the controlling terminal. The solution is this:

import os, sys, time

# Main loop
def main():
    # Drop privs.
    os.setgid(1000) # Replace with desired GID
    os.setuid(1000) # Replace with desired UID

    time.sleep(10)
    sys.exit(0)

if (not os.fork()):
    os.setsid() # Become session leader
    pid = os.fork()

    if (pid):
        # Parent, write PID file
        fp = open('/var/run/my-daemon.pid', 'w')
        fp.write(str(pid))
        fp.flush()

        # Forcibly sync disk
        os.fsync(fp.fileno())
        fp.close()

        os._exit(0)
    else:
        # Child, call main
        main()
else:
    # Parent
    os._exit(0)

6 Responses to “Python: Tips For Writing Daemons”

  1. just a foo Says:

    Most UNIX daemons will also want to set an umask, chdir to some sensible directory and re-open stdin, stdout and stderr

  2. admin Says:

    Very true. os.dup2() is your friend.

  3. Scott Wimer Says:

    There are a few other steps in turning a process into a well behaved daemon. Here are the steps I go through:

    1. Fork # Make new process 1
    1.parent. Exit
    1.child. Decouple from parent
    os.chdir(”/”) # So we don’t tie up a file system
    os.setsid() # Become a session/group leader
    os.umask(0) # Could be other things here as well — allow core’s and what not.
    1.child. Fork # Make new process 2
    2.parent. Exit
    2.child Close all open file descriptors in a pinch, these are 0-1023
    2.child Open stdin, stdout and stderr to /dev/null use os.dup2() for this if you want.
    2.child Congrats, you’re now a daemon. :)

  4. warpedvisions.org » Blog Archive » HOWTO: Write daemons in Python Says:

    […] 5th, 2008 in Links A few good tips on writing daemons in Python, including a Python example of the double-fork console detachment […]

  5. tips Says:

    tips…

    Good websites are few and far between; yours is a pleasure to visit; bookmarking for future visits and I enthusiastically recommend the same!…

  6. Ben Finney Says:

    Other problems not dealt with:

    * Dropping setuid and setgid privileges

    * PID file handling: don’t start if the PID file already exists, otherwise write the PID line to the specified file, remove the PID file when program terminates

    * Signal handling: make sure cleanup is done in response to appropriate signals

    Optional extras usually present in well-behaved daemons:

    * Redirect stdout and stderr to syslog

    * Drop root privileges and switch to a specified user and group id

    * Operate within a chroot jail

    * Respawn on termination

    * Cooperate with operation under initd or inetd

    I’m rather disappointed that these widely-standardised daemon behaviours aren’t present in the Python standard library.

Leave a Reply