-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsonLib_daemonize.py
103 lines (76 loc) · 2.81 KB
/
sonLib_daemonize.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
98
99
100
101
102
103
#!/usr/bin/env python3
# Glenn Hickey 2011
#
#Released under the MIT license, see LICENSE.txt
"""
launch a command as a daemon.
mostly copied from (and see for comments & explanation):
########################################################################
Copyright (C) 2005 Chad J. Schroeder
http://code.activestate.com/recipes/278731/
Disk And Execution MONitor (Daemon)
Configurable daemon behaviors:
1.) The current working directory set to the "/" directory.
2.) The current file creation mode mask set to 0.
3.) Close all open files (1024).
4.) Redirect standard I/O streams to "/dev/null".
A failed call to fork() now raises an exception.
References:
1) Advanced Programming in the Unix Environment: W. Richard Stevens
2) Unix Programming Frequently Asked Questions:
http://www.erlenstar.demon.co.uk/unix/faq_toc.html
########################################################################
handy to break out of a jobTree dependence (which the regular
os.system and subprocess.Popen can't do on their own)
takes single argument: the command line to execute
be careful: the command line is not executed in a shell
example: sonLib_daemonize.py 'ktserver -port 26'
"""
import os
import sys
import resource
import signal
import subprocess
from sonLib.bioio import system
# Default daemon parameters.
# File mode creation mask of the daemon.
# use sonLib.bioio.spawnDaemon() for a python interface
UMASK = 0
# Default working directory for the daemon.
WORKDIR = "/"
# Default maximum for the number of available file descriptors.
MAXFD = 1024
# The standard I/O file descriptors are redirected to /dev/null by default.
if (hasattr(os, "devnull")):
REDIRECT_TO = os.devnull
else:
REDIRECT_TO = "/dev/null"
if __name__ == '__main__':
if len(sys.argv) != 2:
raise Exception("%s: Wrong number of arguments" % sys.argv[0])
pid = os.fork()
if pid > 0:
os._exit(0)
os.chdir("/")
os.setsid()
signal.signal(signal.SIGHUP, signal.SIG_IGN)
os.umask(0)
pid = os.fork()
if pid > 0:
os._exit(0)
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
if (maxfd == resource.RLIM_INFINITY):
maxfd = MAXFD
# Iterate through and close all file descriptors.
for fd in range(0, maxfd):
try:
os.close(fd)
except OSError: # ERROR, fd wasn't open to begin with (ignored)
pass
# Redirect the standard I/O file descriptors to the specified file. Since
os.open(REDIRECT_TO, os.O_RDWR) # standard input (0)
# Duplicate standard input to standard output and standard error.
os.dup2(0, 1) # standard output (1)
os.dup2(0, 2) # standard error (2)
retVal = subprocess.call(sys.argv[1].split(), shell=False, bufsize=-1)
sys.exit(retVal)