1 import sys
2 import os
3 import time
4 import atexit
5 from signal import SIGTERM
6
7
9 """
10 A generic daemon class.
11
12 Usage: subclass the Daemon class and override the run() method
13 """
14
15 - def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
16 self.stdin = stdin
17 self.stdout = stdout
18 self.stderr = stderr
19 self.pidfile = pidfile
20
22 """
23 do the UNIX double-fork magic, see Stevens' "Advanced
24 Programming in the UNIX Environment" for details (ISBN 0201563177)
25 http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
26 """
27 try:
28 pid = os.fork()
29 if pid > 0:
30
31 sys.exit(0)
32 except OSError, e:
33 sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
34 sys.exit(1)
35
36
37 os.chdir("/")
38 os.setsid()
39 os.umask(0)
40
41
42 try:
43 pid = os.fork()
44 if pid > 0:
45
46 sys.exit(0)
47 except OSError, e:
48 sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
49 sys.exit(1)
50
51
52 sys.stdout.flush()
53 sys.stderr.flush()
54 si = file(self.stdin, 'r')
55 so = file(self.stdout, 'a+')
56 se = file(self.stderr, 'a+', 0)
57 os.dup2(si.fileno(), sys.stdin.fileno())
58 os.dup2(so.fileno(), sys.stdout.fileno())
59 os.dup2(se.fileno(), sys.stderr.fileno())
60
61
62 atexit.register(self.delpid)
63 pid = str(os.getpid())
64 file(self.pidfile, 'w+').write("%s\n" % pid)
65
67 os.remove(self.pidfile)
68
70 """
71 Start the daemon
72 """
73
74 try:
75 pf = file(self.pidfile, 'r')
76 pid = int(pf.read().strip())
77 pf.close()
78 except IOError:
79 pid = None
80
81 if pid:
82 message = "pidfile %s already exist. daemon already running?\n"
83 sys.stderr.write(message % self.pidfile)
84 sys.exit(1)
85
86
87 self.daemonize()
88 self.run()
89
91 """
92 Stop the daemon
93 """
94
95 try:
96 pf = file(self.pidfile, 'r')
97 pid = int(pf.read().strip())
98 pf.close()
99 except IOError:
100 pid = None
101
102 if not pid:
103 message = "pidfile %s does not exist. daemon not running?\n"
104 sys.stderr.write(message % self.pidfile)
105 return
106
107
108 try:
109 while 1:
110 os.kill(pid, SIGTERM)
111 time.sleep(0.1)
112 except OSError, err:
113 err = str(err)
114 if err.find("No such process") > 0:
115 if os.path.exists(self.pidfile):
116 os.remove(self.pidfile)
117 else:
118 print str(err)
119 sys.exit(1)
120
122 """
123 Restart the daemon
124 """
125 self.stop()
126 self.start()
127
129 """
130 You should override this method when you subclass Daemon.
131 It will be called after the process has been
132 daemonized by start() or restart().
133 """
134