OptionsParser & Logger is importable from dbuscron
[dbuscron] / dbuscron / daemonize.py
1 import os, sys
2
3 def daemonize(logfile=None, errfile=None, pidfile=None):
4     devnull = os.devnull if hasattr(os, 'devnull') else '/dev/null'
5
6     initwd = os.getcwd()
7     def absolutize(path):
8         if path.startswith('/'):
9             return path
10         return os.path.join(initwd, path)
11
12     try:
13         if os.fork() == 0:
14             os.setsid()
15             if os.fork() == 0:
16                 os.chdir('/')
17                 os.umask(0)
18             else:
19                 os._exit(0)
20         else:
21             os._exit(0)
22     except OSError, e:
23         raise Exception('Failed daemonization: %s' % str(e))
24
25     for i in range(0, 3):
26         os.close(i)
27
28     os.open(devnull, os.O_RDWR)
29
30     def open_trunc(fname):
31         f = os.open(fname, \
32             os.O_WRONLY|os.O_CREAT)
33         os.ftruncate(f, 0)
34         return f
35
36     def open_or_dup(fname, fd=None):
37         if fname:
38             return open_trunc(absolutize(fname))
39         elif fd:
40             os.dup2(*fd)
41
42     open_or_dup(logfile, (0, 1))
43     open_or_dup(errfile, (1, 2))
44
45     pid = os.getpid()
46     if pidfile:
47         pidfile = absolutize(pidfile)
48         fd = open_trunc(pidfile)
49         os.write(fd, str(pid))
50         os.close(fd)
51
52         def remove_pidfile():
53             os.unlink(pidfile)
54         sys.exitfunc = remove_pidfile
55
56     return pid
57