-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodule.py
97 lines (80 loc) · 2.56 KB
/
module.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import sys, os, time, atexit, signal
"""
Ref by https://gist.github.com/andreif/cbb71b0498589dac93cb
"""
class daemon:
def __init__(self, pidfile):
self.pidfile = pidfile
def __delete_pid(self):
os.remove(self.pidfile)
def daemonize(self):
"""Daemonize class"""
# create child
try:
pid = os.fork()
if pid > 0:
# suicide parent
sys.exit(0)
except OSError as err:
sys.stderr.write(f'fork failed: {err}')
sys.exit(-1)
# adopted init child
os.chdir('/')
os.setsid()
os.umask(0)
# redirect file descriptor 0, 1, 2 (stdin, stdout, stderr) to /dev/null
sys.stdout.flush()
sys.stderr.flush()
stdi = open(os.devnull, 'r')
stdo = open(os.devnull, 'a+')
stde = open(os.devnull, 'a+')
os.dup2(stdi.fileno(), sys.stdin.fileno())
os.dup2(stdo.fileno(), sys.stdout.fileno())
os.dup2(stde.fileno(), sys.stdout.fileno())
atexit.register(self.__delete_pid)
pid = os.getpid()
with open(self.pidfile, 'w+') as f:
f.write(str(pid) + '\n')
def start(self):
try:
with open(self.pidfile, 'r') as pf:
pid = int(pf.read().strip())
except IOError:
pid = None
if pid:
message = f"pidfile {self.pidfile} already exist. Please check daemon already running."
sys.stderr.write(message)
sys.exit(1)
self.daemonize()
try:
self.run()
except Exception as e:
message = "It seems daemon library using without inherit. " +\
f"Please override self.run(). ERROR: {e}"
sys.stderr.write(message)
def stop(self):
try:
with open(self.pidfile, 'r') as pf:
pid = int(pf.read().strip())
except IOError:
pid = None
if not pid:
message = f"pidfile {self.pidfile} does not exist. Please check daemon running."
sys.stderr.write(message)
sys.exit(1)
try:
while True:
os.kill(pid, signal.SIGTERM)
time.sleep(0.1)
except OSError as e:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print(e)
sys.exit(1)
def restart(self):
self.stop()
self.start()
# TODO: make status
def status(self):
"""status"""