]> kaliko git repositories - python-daemon.git/blobdiff - src/daemon.py
Some cleanup and documentation
[python-daemon.git] / src / daemon.py
index 9bb945f0ed7d1ff20625f2017487fdc4d9878f25..96cde84e9ec3a043dd49f3b557a28e56b5c438b8 100644 (file)
@@ -3,7 +3,7 @@
 # Public Domain
 #
 # Copyright 2007, 2009 Sander Marechal <s.marechal@jejik.com>
-# Copyright 2010, 2011 Jack Kaliko <efrim@azylum.org>
+# Copyright 2010, 2011, 2012 Jack Kaliko <efrim@azylum.org>
 #
 # http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
 
@@ -20,7 +20,7 @@ class Daemon(object):
 
     Usage: subclass the Daemon class and override the run() method
     """
-    version = "0.2"
+    version = "0.4"
 
     def __init__(self, pidfile,
             stdin='/dev/null',
@@ -34,9 +34,15 @@ class Daemon(object):
 
     def daemonize(self):
         """
-        do the UNIX double-fork magic, see Stevens' "Advanced
-        Programming in the UNIX Environment" for details (ISBN 0201563177)
-        http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
+        Do the UNIX double-fork magic.
+        see W. Richard Stevens, "Advanced Programming in the Unix Environment"
+        for details (ISBN 0201563177)
+
+        Short explanation:
+            Unix processes belong to "process group" which in turn lies within a "session".
+            A session can have a controlling tty.
+            Forking twice allows to detach the session from a possible tty.
+            The process lives then within the init process.
         """
         try:
             pid = os.fork()
@@ -44,11 +50,11 @@ class Daemon(object):
                 # exit first parent
                 sys.exit(0)
         except OSError, e:
-            sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
+            sys.stderr.write('fork #1 failed: %d (%s)\n' % (e.errno, e.strerror))
             sys.exit(1)
 
         # Decouple from parent environment
-        os.chdir("/")
+        os.chdir('/')
         os.setsid()
         self.umask = os.umask(0)
 
@@ -59,7 +65,7 @@ class Daemon(object):
                 # exit from second parent
                 sys.exit(0)
         except OSError, e:
-            sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
+            sys.stderr.write('fork #2 failed: %d (%s)\n' % (e.errno, e.strerror))
             sys.exit(1)
 
         self.write_pid()
@@ -84,10 +90,8 @@ class Daemon(object):
         try:
             os.umask(self.umask)
             file(self.pidfile, 'w').write('%s\n' % pid)
-            #except IOError, wpid_err:
         except Exception, wpid_err:
-            sys.stderr.write(u'Error trying to write pid file to %s: %s\n' %
-                   (unicode(self.pidfile, 'utf-8'), wpid_err))
+            sys.stderr.write(u'Error trying to write pid file: %s\n' % wpid_err)
             sys.exit(1)
         os.umask(0)
         atexit.register(self.delpid)
@@ -100,7 +104,11 @@ class Daemon(object):
         sys.exit(1)
 
     def delpid(self):
-        os.unlink(self.pidfile)
+        try:
+            os.unlink(self.pidfile)
+        except OSError as err:
+            message = 'Error trying to remove PID file: %s\n'
+            sys.stderr.write(message % err)
 
     def start(self):
         """
@@ -115,7 +123,7 @@ class Daemon(object):
             pid = None
 
         if pid:
-            message = "pidfile %s already exist. Daemon already running?\n"
+            message = 'pidfile %s already exist. Daemon already running?\n'
             sys.stderr.write(message % self.pidfile)
             sys.exit(1)
 
@@ -144,7 +152,7 @@ class Daemon(object):
             pid = None
 
         if not pid:
-            message = "pidfile %s does not exist. Daemon not running?\n"
+            message = 'pidfile %s does not exist. Is the Daemon running?\n'
             sys.stderr.write(message % self.pidfile)
             return  # not an error in a restart
 
@@ -153,14 +161,13 @@ class Daemon(object):
             os.kill(pid, SIGTERM)
             time.sleep(0.1)
         except OSError, err:
-            err = str(err)
-            if err.find("No such process") > 0:
+            if err.errno == 3:
                 if os.path.exists(self.pidfile):
-                    message = "Daemon not running? removing pid file %s.\n"
+                    message = "Daemon's not running? removing pid file %s.\n"
                     sys.stderr.write(message % self.pidfile)
                     os.remove(self.pidfile)
             else:
-                print str(err)
+                sys.stderr.write(err.strerror)
                 sys.exit(1)
 
     def restart(self):
@@ -187,13 +194,5 @@ class Daemon(object):
         called after the process has been daemonized by start() or restart().
         """
 
-
-def main():
-    pass
-
-# Script starts here
-if __name__ == '__main__':
-    main()
-
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab