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 Exception, wpid_err:
88 sys.stderr.write(u'Error trying to write pid file: %s\n' % wpid_err)
91 atexit.register(self.delpid)
93 def signal_management(self):
94 # Declare signal handlers
95 signal(SIGTERM, self.exit_handler)
97 def exit_handler(self, signum, frame):
102 os.unlink(self.pidfile)
103 except OSError as err:
104 message = 'Error trying to remove PID file: %s\n'
105 sys.stderr.write(message % err)
111 # Check for a pidfile to see if the daemon already runs
113 pf = file(self.pidfile, 'r')
114 pid = int(pf.read().strip())
120 message = "pidfile %s already exist. Daemon already running?\n"
121 sys.stderr.write(message % self.pidfile)
128 def foreground(self):
130 Foreground/debug mode
133 atexit.register(self.shutdown)
140 # Get the pid from the pidfile
142 pf = file(self.pidfile, 'r')
143 pid = int(pf.read().strip())
149 message = "pidfile %s does not exist. Is the Daemon running?\n"
150 sys.stderr.write(message % self.pidfile)
151 return # not an error in a restart
153 # Try killing the daemon process
155 os.kill(pid, SIGTERM)
159 if os.path.exists(self.pidfile):
160 message = "Daemon's not running? removing pid file %s.\n"
161 sys.stderr.write(message % self.pidfile)
162 os.remove(self.pidfile)
164 sys.stderr.write(err.strerror)
176 You should override this method when you subclass Daemon. It will be
177 called when the process is being stopped.
179 Daemon() uses atexit to call Daemon().shutdown(), as a consequence
180 shutdown and any other functions registered via this module are not
181 called when the program is killed by an un-handled/unknown signal.
182 This is the reason of Daemon().signal_management() existence.
187 You should override this method when you subclass Daemon. It will be
188 called after the process has been daemonized by start() or restart().
196 if __name__ == '__main__':
200 # vim: ai ts=4 sw=4 sts=4 expandtab