1 # -*- coding: utf-8 -*-
4 # Copyright 2007, 2009 Sander Marechal <s.marechal@jejik.com>
5 # http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
7 # Copyright 2010, 2011 Jack Kaliko <efrim@azylum.org>
8 # https://gitorious.org/python-daemon
10 # This file is part of MPD_sima
12 # MPD_sima is free software: you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation, either version 3 of the License, or
15 # (at your option) any later version.
17 # MPD_sima is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with MPD_sima. If not, see <http://www.gnu.org/licenses/>.
29 from signal import signal, SIGTERM, SIGHUP, SIGUSR1
34 A generic daemon class.
36 Usage: subclass the Daemon class and override the run() method
38 Daemon([pidfile[, stdin[, stdout[, stderr]]]])
40 pidfile : file to write pid to (default no pid file writen)
41 stdin : standard input file descriptor (default to /dev/null)
42 stdout : standard output file descriptor (default to /dev/null)
43 stderr : standard error file descriptorr (default to /dev/null)
47 def __init__(self, pidfile,
54 self.pidfile = pidfile
59 Do the UNIX double-fork magic.
60 see W. Richard Stevens, "Advanced Programming in the Unix Environment"
61 for details (ISBN 0201563177)
64 Unix processes belong to "process group" which in turn lies within a
65 "session". A session can have a controlling tty.
66 Forking twice allows to detach the session from a possible tty.
67 The process lives then within the init process.
75 sys.stderr.write('fork #1 failed: {0.errno:d} ({0.strerror})\n'.format(e))
78 # Decouple from parent environment
81 self.umask = os.umask(0)
87 # exit from second parent
90 sys.stderr.write('fork #2 failed: {0.errno:d} ({0.strerror})\n'.format(e))
94 # redirect standard file descriptors
97 # TODO: binary or txt mode?
98 si = open(self.stdin, mode='rb')
99 so = open(self.stdout, mode='ab+')
100 se = open(self.stderr, mode='ab+', buffering=0)
101 os.dup2(si.fileno(), sys.stdin.fileno())
102 os.dup2(so.fileno(), sys.stdout.fileno())
103 os.dup2(se.fileno(), sys.stderr.fileno())
105 atexit.register(self.shutdown)
106 self.signal_management()
112 pid = str(os.getpid())
115 open(self.pidfile, 'w').write('%s\n' % pid)
116 except Exception as wpid_err:
117 sys.stderr.write('Error trying to write pid file: {}\n'.format(wpid_err))
120 atexit.register(self.delpid)
122 def signal_management(self):
123 """Declare signal handlers
125 signal(SIGTERM, self.exit_handler)
126 signal(SIGHUP, self.hup_handler)
127 signal(SIGUSR1, self.hup_handler)
129 def exit_handler(self, signum, frame):
132 def hup_handler(self, signum, frame):
137 """Remove PID file"""
139 os.unlink(self.pidfile)
140 except OSError as err:
141 message = 'Error trying to remove PID file: {}\n'
142 sys.stderr.write(message.format(err))
148 # Check for a pidfile to see if the daemon already runs
150 pf = open(self.pidfile, 'r')
151 pid = int(pf.read().strip())
157 message = 'pidfile {0.pidfile} already exist. Daemon already running?\n'
158 sys.stderr.write(message.format(self))
165 def foreground(self):
167 Foreground/debug mode
170 atexit.register(self.shutdown)
177 # Get the pid from the pidfile
179 pf = open(self.pidfile, 'r')
180 pid = int(pf.read().strip())
186 message = 'pidfile {0.pidfile} does not exist. Is the Daemon running?\n'
187 sys.stderr.write(message.format(self))
188 return # not an error in a restart
190 # Try killing the daemon process
192 os.kill(pid, SIGTERM)
194 except OSError as err:
196 if os.path.exists(self.pidfile):
197 message = "Daemon's not running? removing pid file {0.pidfile}.\n"
198 sys.stderr.write(message.format(self))
199 os.remove(self.pidfile)
201 sys.stderr.write(err.strerror)
213 You should override this method when you subclass Daemon. It will be
214 called when the process is being stopped.
216 Daemon() uses atexit to call Daemon().shutdown(), as a consequence
217 shutdown and any other functions registered via this module are not
218 called when the program is killed by an un-handled/unknown signal.
219 This is the reason of Daemon().signal_management() existence.
224 You should override this method when you subclass Daemon. It will be
225 called after the process has been daemonized by start() or restart().
229 # vim: ai ts=4 sw=4 sts=4 expandtab