1 # -*- coding: utf-8 -*-
5 # Copyright 2007, 2009 Sander Marechal <s.marechal@jejik.com>
6 # Copyright 2010, 2011 Jack Kaliko <efrim@azylum.org>
8 # http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
14 from signal import signal, SIGTERM
19 A generic daemon class.
21 Usage: subclass the Daemon class and override the run() method
25 def __init__(self, pidfile,
32 self.pidfile = pidfile
37 do the UNIX double-fork magic, see Stevens' "Advanced
38 Programming in the UNIX Environment" for details (ISBN 0201563177)
39 http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
47 sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
50 # Decouple from parent environment
53 self.umask = os.umask(0)
59 # exit from second parent
62 sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
66 # redirect standard file descriptors
69 si = file(self.stdin, 'r')
70 so = file(self.stdout, 'a+')
71 se = file(self.stderr, 'a+', 0)
72 os.dup2(si.fileno(), sys.stdin.fileno())
73 os.dup2(so.fileno(), sys.stdout.fileno())
74 os.dup2(se.fileno(), sys.stderr.fileno())
76 atexit.register(self.shutdown)
77 self.signal_management()
83 pid = str(os.getpid())
86 file(self.pidfile, 'w').write('%s\n' % pid)
87 #except IOError, wpid_err:
88 except Exception, wpid_err:
89 sys.stderr.write(u'Error trying to write pid file to %s: %s\n' %
90 (unicode(self.pidfile, 'utf-8'), wpid_err))
93 atexit.register(self.delpid)
95 def signal_management(self):
96 # Declare signal handlers
97 signal(SIGTERM, self.exit_handler)
99 def exit_handler(self, signum, frame):
103 os.unlink(self.pidfile)
109 # Check for a pidfile to see if the daemon already runs
111 pf = file(self.pidfile, 'r')
112 pid = int(pf.read().strip())
118 message = "pidfile %s already exist. Daemon already running?\n"
119 sys.stderr.write(message % self.pidfile)
126 def foreground(self):
128 Foreground/debug mode
131 atexit.register(self.shutdown)
138 # Get the pid from the pidfile
140 pf = file(self.pidfile, 'r')
141 pid = int(pf.read().strip())
147 message = "pidfile %s does not exist. Is the Daemon running?\n"
148 sys.stderr.write(message % self.pidfile)
149 return # not an error in a restart
151 # Try killing the daemon process
153 os.kill(pid, SIGTERM)
157 if os.path.exists(self.pidfile):
158 message = "Daemon's not running? removing pid file %s.\n"
159 sys.stderr.write(message % self.pidfile)
160 os.remove(self.pidfile)
174 You should override this method when you subclass Daemon. It will be
175 called when the process is being stopped.
177 Daemon() uses atexit to call Daemon().shutdown(), as a consequence
178 shutdown and any other functions registered via this module are not
179 called when the program is killed by an un-handled/unknown signal.
180 This is the reason of Daemon().signal_management() existence.
185 You should override this method when you subclass Daemon. It will be
186 called after the process has been daemonized by start() or restart().
194 if __name__ == '__main__':
198 # vim: ai ts=4 sw=4 sts=4 expandtab