# 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/
Usage: subclass the Daemon class and override the run() method
"""
- version = "0.2"
+ version = "0.4"
def __init__(self, pidfile,
stdin='/dev/null',
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()
# 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)
# 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()
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)
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):
"""
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)
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
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):
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