1 # -*- coding: utf-8 -*-
5 # Copyright 2007, 2009 Sander Marechal <s.marechal@jejik.com>
6 # http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
8 # Copyright 2010, 2011 Jack Kaliko <efrim@azylum.org>
9 # https://gitorious.org/python-daemon
11 # This file is part of MPD_sima
13 # MPD_sima is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
18 # MPD_sima is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with MPD_sima. If not, see <http://www.gnu.org/licenses/>.
30 from signal import signal, SIGTERM, SIGHUP, SIGUSR1
35 A generic daemon class.
37 Usage: subclass the Daemon class and override the run() method
39 Daemon([pidfile[, stdin[, stdout[, stderr]]]])
41 pidfile : file to write pid to (default no pid file writen)
42 stdin : standard input file descriptor (default to /dev/null)
43 stdout : standard output file descriptor (default to /dev/null)
44 stderr : standard error file descriptorr (default to /dev/null)
48 def __init__(self, pidfile,
55 self.pidfile = pidfile
60 Do the UNIX double-fork magic.
61 see W. Richard Stevens, "Advanced Programming in the Unix Environment"
62 for details (ISBN 0201563177)
65 Unix processes belong to "process group" which in turn lies within a "session".
66 A session can have a controlling tty.
67 Forking twice allows to detach the session from a possible tty.
68 The process lives then within the init process.
76 sys.stderr.write('fork #1 failed: {0.errno:d} ({0.strerror})\n'.format(e))
79 # Decouple from parent environment
82 self.umask = os.umask(0)
88 # exit from second parent
91 sys.stderr.write('fork #2 failed: {0.errno:d} ({0.strerror})\n'.format(e))
95 # redirect standard file descriptors
98 # TODO: binary or txt mode?
99 si = open(self.stdin, mode='rb')
100 so = open(self.stdout, mode='ab+')
101 se = open(self.stderr, mode='ab+', buffering=0)
102 os.dup2(si.fileno(), sys.stdin.fileno())
103 os.dup2(so.fileno(), sys.stdout.fileno())
104 os.dup2(se.fileno(), sys.stderr.fileno())
106 atexit.register(self.shutdown)
107 self.signal_management()
113 pid = str(os.getpid())
116 open(self.pidfile, 'w').write('%s\n' % pid)
117 except Exception as wpid_err:
118 sys.stderr.write('Error trying to write pid file: {}\n'.format(wpid_err))
121 atexit.register(self.delpid)
123 def signal_management(self):
124 """Declare signal handlers
126 signal(SIGTERM, self.exit_handler)
127 signal(SIGHUP, self.hup_handler)
128 signal(SIGUSR1, self.hup_handler)
130 def exit_handler(self, signum, frame):
133 def hup_handler(self, signum, frame):
138 """Remove PID file"""
140 os.unlink(self.pidfile)
141 except OSError as err:
142 message = 'Error trying to remove PID file: {}\n'
143 sys.stderr.write(message.format(err))
149 # Check for a pidfile to see if the daemon already runs
151 pf = open(self.pidfile, 'r')
152 pid = int(pf.read().strip())
158 message = 'pidfile {0.pidfile} already exist. Daemon already running?\n'
159 sys.stderr.write(message.format(self))
166 def foreground(self):
168 Foreground/debug mode
171 atexit.register(self.shutdown)
178 # Get the pid from the pidfile
180 pf = open(self.pidfile, 'r')
181 pid = int(pf.read().strip())
187 message = 'pidfile {0.pidfile} does not exist. Is the Daemon running?\n'
188 sys.stderr.write(message.format(self))
189 return # not an error in a restart
191 # Try killing the daemon process
193 os.kill(pid, SIGTERM)
195 except OSError as err:
197 if os.path.exists(self.pidfile):
198 message = "Daemon's not running? removing pid file {0.pidfile}.\n"
199 sys.stderr.write(message.format(self))
200 os.remove(self.pidfile)
202 sys.stderr.write(err.strerror)
214 You should override this method when you subclass Daemon. It will be
215 called when the process is being stopped.
217 Daemon() uses atexit to call Daemon().shutdown(), as a consequence
218 shutdown and any other functions registered via this module are not
219 called when the program is killed by an un-handled/unknown signal.
220 This is the reason of Daemon().signal_management() existence.
225 You should override this method when you subclass Daemon. It will be
226 called after the process has been daemonized by start() or restart().
230 # vim: ai ts=4 sw=4 sts=4 expandtab