1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """A daemonize function (for Unices)"""
19
20 __docformat__ = "restructuredtext en"
21
22 import os
23 import errno
24 import signal
25 import sys
26 import time
27 import warnings
28
30 """Change process user and group ID
31
32 Argument is a numeric user id or a user name"""
33 try:
34 from pwd import getpwuid
35 passwd = getpwuid(int(user))
36 except ValueError:
37 from pwd import getpwnam
38 passwd = getpwnam(user)
39
40 if hasattr(os, 'initgroups'):
41 os.initgroups(passwd.pw_name, passwd.pw_gid)
42 else:
43 import ctypes
44 if ctypes.CDLL(None).initgroups(passwd.pw_name, passwd.pw_gid) < 0:
45 err = ctypes.c_int.in_dll(ctypes.pythonapi,"errno").value
46 raise OSError(err, os.strerror(err), 'initgroups')
47 os.setgid(passwd.pw_gid)
48 os.setuid(passwd.pw_uid)
49 os.environ['HOME'] = passwd.pw_dir
50
51
52 -def daemonize(pidfile=None, uid=None, umask=077):
53 """daemonize a Unix process. Set paranoid umask by default.
54
55 Return 1 in the original process, 2 in the first fork, and None for the
56 second fork (eg daemon process).
57 """
58
59
60
61 if os.fork():
62 return 1
63
64 os.setsid()
65
66
67
68 if os.fork():
69 return 2
70
71 os.chdir('/')
72
73 if umask is not None:
74 os.umask(umask)
75
76 null = os.open('/dev/null', os.O_RDWR)
77 for i in range(3):
78 try:
79 os.dup2(null, i)
80 except OSError, e:
81 if e.errno != errno.EBADF:
82 raise
83 os.close(null)
84
85 warnings.filterwarnings('ignore')
86
87 if pidfile:
88
89
90 piddir = os.path.dirname(pidfile)
91 if not os.path.exists(piddir):
92 os.makedirs(piddir)
93 f = file(pidfile, 'w')
94 f.write(str(os.getpid()))
95 f.close()
96 os.chmod(pidfile, 0644)
97
98 if uid:
99 setugid(uid)
100 return None
101