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