Difference between revisions of "Daemonize Python"

From Noah.org
Jump to navigationJump to search
m
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[Category:Engineering]]
 
[[Category:Engineering]]
 
[[Category:Python]]
 
[[Category:Python]]
== Python Daemonize source ==
+
[[Category:Free_Software]]
<pre>
 
#!/usr/bin/env python
 
import sys, os, signal
 
  
'''This module is used to fork the current process into a daemon.
+
This short module shows the correct way to create a UNIX daemon process in Python.
  
Almost none of this is necessary (or advisable) if your daemon
+
Click here to download: [http://www.noah.org/engineering/src/python/daemonize.py daemonize.py]
is being started by inetd. In that case, stdin, stdout and stderr are
+
<include src="/home/noahspurrier/noah.org/engineering/src/python/daemonize.py" highlight="python" />
all set up for you to refer to the network connection, and the fork()s
 
and session manipulation should not be done (to avoid confusing inetd).
 
Only the chdir() and umask() steps remain as useful.
 
 
 
References:
 
    UNIX Programming FAQ
 
        1.7 How do I get my program to act like a daemon?
 
        http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
 
 
 
    Advanced Programming in the Unix Environment
 
        W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7.
 
'''
 
 
 
def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
 
    '''This forks the current process into a daemon.
 
    The stdin, stdout, and stderr arguments are file names that
 
    will be opened and be used to replace the standard file descriptors
 
    in sys.stdin, sys.stdout, and sys.stderr.
 
    These arguments are optional and default to /dev/null.
 
    Note that stderr is opened unbuffered, so
 
    if it shares a file with stdout then interleaved output
 
    may not appear in the order that you expect.
 
    '''
 
 
 
    # Do first fork.
 
    try:
 
        pid = os.fork()
 
        if pid > 0:
 
            return pid
 
    except OSError, e:
 
return (e.errno, e.strerror) # Fork failed.
 
 
 
    # Decouple from parent environment.
 
    os.setsid()
 
 
 
    # When the first child terminates, all processes in the second child
 
    # are sent a SIGHUP. This causes it to be ignored.
 
    signal.signal(signal.SIGHUP, signal.SIG_IGN)
 
 
 
    # Do second fork.
 
    try:
 
        pid = os.fork()
 
        if pid > 0:
 
            os._exit(0)  # Exit second parent.
 
    except OSError, e:
 
        sys.stderr.write ("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror) )
 
        os._exit(1)
 
 
 
    # Now I am a daemon!
 
   
 
    os.chdir("/") # don't hold open any directories
 
    os.umask(0)
 
 
 
    # Close open files. Try the system configuration variable, SC_OPEN_MAX,
 
    # for the maximum number of open files to close. If it doesn't exist, use 1024.
 
    try:
 
        maxfd = os.sysconf("SC_OPEN_MAX")
 
    except (AttributeError, ValueError):
 
        maxfd = 1024
 
    for fd in range(3, maxfd):
 
        try:
 
            os.close(fd)
 
        except OSError:  # ERROR (ignore)
 
            pass
 
 
 
    # Redirect standard file descriptors.
 
    si = open(stdin, 'r')
 
    so = open(stdout, 'a+')
 
    se = open(stderr, 'a+', 0)
 
    os.dup2(si.fileno(), sys.stdin.fileno())
 
    os.dup2(so.fileno(), sys.stdout.fileno())
 
    os.dup2(se.fileno(), sys.stderr.fileno())
 
    return 0
 
 
 
def main ():
 
    '''This is an example main function run by the daemon.
 
    This prints a count and timestamp once per second.
 
    '''
 
    import time
 
    sys.stdout.write ('Daemon started with pid %d\n' % os.getpid() )
 
    sys.stdout.write ('Daemon stdout output\n')
 
    sys.stderr.write ('Daemon stderr output\n')
 
    c = 0
 
    while 1:
 
        sys.stdout.write ('%d: %s\n' % (c, time.ctime(time.time())) )
 
        sys.stdout.flush()
 
        c = c + 1
 
        time.sleep(1)
 
 
 
if __name__ == "__main__":
 
    print str(daemonize('/dev/null','/tmp/daemon.log','/tmp/daemon.log'))
 
    main()
 
</pre>
 

Revision as of 04:35, 26 March 2010


This short module shows the correct way to create a UNIX daemon process in Python.

Click here to download: daemonize.py <include src="/home/noahspurrier/noah.org/engineering/src/python/daemonize.py" highlight="python" />