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
29 from six.moves import range
30
32 """Change process user and group ID
33
34 Argument is a numeric user id or a user name"""
35 try:
36 from pwd import getpwuid
37 passwd = getpwuid(int(user))
38 except ValueError:
39 from pwd import getpwnam
40 passwd = getpwnam(user)
41
42 if hasattr(os, 'initgroups'):
43 os.initgroups(passwd.pw_name, passwd.pw_gid)
44 else:
45 import ctypes
46 if ctypes.CDLL(None).initgroups(passwd.pw_name, passwd.pw_gid) < 0:
47 err = ctypes.c_int.in_dll(ctypes.pythonapi,"errno").value
48 raise OSError(err, os.strerror(err), 'initgroups')
49 os.setgid(passwd.pw_gid)
50 os.setuid(passwd.pw_uid)
51 os.environ['HOME'] = passwd.pw_dir
52
53
54 -def daemonize(pidfile=None, uid=None, umask=0o77):
55 """daemonize a Unix process. Set paranoid umask by default.
56
57 Return 1 in the original process, 2 in the first fork, and None for the
58 second fork (eg daemon process).
59 """
60
61
62
63 if os.fork():
64 return 1
65
66 os.setsid()
67
68
69
70 if os.fork():
71 return 2
72
73 os.chdir('/')
74
75 null = os.open('/dev/null', os.O_RDWR)
76 for i in range(3):
77 try:
78 os.dup2(null, i)
79 except OSError as e:
80 if e.errno != errno.EBADF:
81 raise
82 os.close(null)
83
84 warnings.filterwarnings('ignore')
85
86 if pidfile:
87
88
89 piddir = os.path.dirname(pidfile)
90 if not os.path.exists(piddir):
91 os.makedirs(piddir)
92 f = file(pidfile, 'w')
93 f.write(str(os.getpid()))
94 f.close()
95
96 if umask is not None:
97 os.umask(umask)
98
99 if uid:
100 setugid(uid)
101 return None
102