Index: trunk/udpmcast/util.py |
— | — | @@ -0,0 +1,78 @@ |
| 2 | +# util.py |
| 3 | +# utility functions shared by udpmcast and htcpseqcheck |
| 4 | + |
| 5 | +import os, signal |
| 6 | + |
| 7 | +def createDaemon(): |
| 8 | + """ |
| 9 | + Detach a process from the controlling terminal and run it in the |
| 10 | + background as a daemon. |
| 11 | + """ |
| 12 | + |
| 13 | + try: |
| 14 | + # Fork a child process so the parent can exit. This will return control |
| 15 | + # to the command line or shell. This is required so that the new process |
| 16 | + # is guaranteed not to be a process group leader. We have this guarantee |
| 17 | + # because the process GID of the parent is inherited by the child, but |
| 18 | + # the child gets a new PID, making it impossible for its PID to equal its |
| 19 | + # PGID. |
| 20 | + pid = os.fork() |
| 21 | + except OSError, e: |
| 22 | + return((e.errno, e.strerror)) # ERROR (return a tuple) |
| 23 | + |
| 24 | + if (pid == 0): # The first child. |
| 25 | + |
| 26 | + # Next we call os.setsid() to become the session leader of this new |
| 27 | + # session. The process also becomes the process group leader of the |
| 28 | + # new process group. Since a controlling terminal is associated with a |
| 29 | + # session, and this new session has not yet acquired a controlling |
| 30 | + # terminal our process now has no controlling terminal. This shouldn't |
| 31 | + # fail, since we're guaranteed that the child is not a process group |
| 32 | + # leader. |
| 33 | + os.setsid() |
| 34 | + |
| 35 | + # When the first child terminates, all processes in the second child |
| 36 | + # are sent a SIGHUP, so it's ignored. |
| 37 | + signal.signal(signal.SIGHUP, signal.SIG_IGN) |
| 38 | + |
| 39 | + try: |
| 40 | + # Fork a second child to prevent zombies. Since the first child is |
| 41 | + # a session leader without a controlling terminal, it's possible for |
| 42 | + # it to acquire one by opening a terminal in the future. This second |
| 43 | + # fork guarantees that the child is no longer a session leader, thus |
| 44 | + # preventing the daemon from ever acquiring a controlling terminal. |
| 45 | + pid = os.fork() # Fork a second child. |
| 46 | + except OSError, e: |
| 47 | + return((e.errno, e.strerror)) # ERROR (return a tuple) |
| 48 | + |
| 49 | + if (pid == 0): # The second child. |
| 50 | + # Ensure that the daemon doesn't keep any directory in use. Failure |
| 51 | + # to do this could make a filesystem unmountable. |
| 52 | + os.chdir("/") |
| 53 | + # Give the child complete control over permissions. |
| 54 | + os.umask(0) |
| 55 | + else: |
| 56 | + os._exit(0) # Exit parent (the first child) of the second child. |
| 57 | + else: |
| 58 | + os._exit(0) # Exit parent of the first child. |
| 59 | + |
| 60 | + # Close all open files. Try the system configuration variable, SC_OPEN_MAX, |
| 61 | + # for the maximum number of open files to close. If it doesn't exist, use |
| 62 | + # the default value (configurable). |
| 63 | + try: |
| 64 | + maxfd = os.sysconf("SC_OPEN_MAX") |
| 65 | + except (AttributeError, ValueError): |
| 66 | + maxfd = 256 # default maximum |
| 67 | + |
| 68 | + for fd in range(0, maxfd): |
| 69 | + try: |
| 70 | + os.close(fd) |
| 71 | + except OSError: # ERROR (ignore) |
| 72 | + pass |
| 73 | + |
| 74 | + # Redirect the standard file descriptors to /dev/null. |
| 75 | + os.open("/dev/null", os.O_RDONLY) # standard input (0) |
| 76 | + os.open("/dev/null", os.O_RDWR) # standard output (1) |
| 77 | + os.open("/dev/null", os.O_RDWR) # standard error (2) |
| 78 | + |
| 79 | + return(0) |
Property changes on: trunk/udpmcast/util.py |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 80 | + text/plain |
Index: trunk/udpmcast/udpmcast.py |
— | — | @@ -6,84 +6,10 @@ |
7 | 7 | # |
8 | 8 | # $Id$ |
9 | 9 | |
10 | | -import socket, getopt, sys, os, signal, pwd, grp |
| 10 | +import socket, getopt, sys, pwd, grp |
11 | 11 | |
12 | 12 | debugging = False |
13 | 13 | |
14 | | -def createDaemon(): |
15 | | - """ |
16 | | - Detach a process from the controlling terminal and run it in the |
17 | | - background as a daemon. |
18 | | - """ |
19 | | - |
20 | | - try: |
21 | | - # Fork a child process so the parent can exit. This will return control |
22 | | - # to the command line or shell. This is required so that the new process |
23 | | - # is guaranteed not to be a process group leader. We have this guarantee |
24 | | - # because the process GID of the parent is inherited by the child, but |
25 | | - # the child gets a new PID, making it impossible for its PID to equal its |
26 | | - # PGID. |
27 | | - pid = os.fork() |
28 | | - except OSError, e: |
29 | | - return((e.errno, e.strerror)) # ERROR (return a tuple) |
30 | | - |
31 | | - if (pid == 0): # The first child. |
32 | | - |
33 | | - # Next we call os.setsid() to become the session leader of this new |
34 | | - # session. The process also becomes the process group leader of the |
35 | | - # new process group. Since a controlling terminal is associated with a |
36 | | - # session, and this new session has not yet acquired a controlling |
37 | | - # terminal our process now has no controlling terminal. This shouldn't |
38 | | - # fail, since we're guaranteed that the child is not a process group |
39 | | - # leader. |
40 | | - os.setsid() |
41 | | - |
42 | | - # When the first child terminates, all processes in the second child |
43 | | - # are sent a SIGHUP, so it's ignored. |
44 | | - signal.signal(signal.SIGHUP, signal.SIG_IGN) |
45 | | - |
46 | | - try: |
47 | | - # Fork a second child to prevent zombies. Since the first child is |
48 | | - # a session leader without a controlling terminal, it's possible for |
49 | | - # it to acquire one by opening a terminal in the future. This second |
50 | | - # fork guarantees that the child is no longer a session leader, thus |
51 | | - # preventing the daemon from ever acquiring a controlling terminal. |
52 | | - pid = os.fork() # Fork a second child. |
53 | | - except OSError, e: |
54 | | - return((e.errno, e.strerror)) # ERROR (return a tuple) |
55 | | - |
56 | | - if (pid == 0): # The second child. |
57 | | - # Ensure that the daemon doesn't keep any directory in use. Failure |
58 | | - # to do this could make a filesystem unmountable. |
59 | | - os.chdir("/") |
60 | | - # Give the child complete control over permissions. |
61 | | - os.umask(0) |
62 | | - else: |
63 | | - os._exit(0) # Exit parent (the first child) of the second child. |
64 | | - else: |
65 | | - os._exit(0) # Exit parent of the first child. |
66 | | - |
67 | | - # Close all open files. Try the system configuration variable, SC_OPEN_MAX, |
68 | | - # for the maximum number of open files to close. If it doesn't exist, use |
69 | | - # the default value (configurable). |
70 | | - try: |
71 | | - maxfd = os.sysconf("SC_OPEN_MAX") |
72 | | - except (AttributeError, ValueError): |
73 | | - maxfd = 256 # default maximum |
74 | | - |
75 | | - for fd in range(0, maxfd): |
76 | | - try: |
77 | | - os.close(fd) |
78 | | - except OSError: # ERROR (ignore) |
79 | | - pass |
80 | | - |
81 | | - # Redirect the standard file descriptors to /dev/null. |
82 | | - os.open("/dev/null", os.O_RDONLY) # standard input (0) |
83 | | - os.open("/dev/null", os.O_RDWR) # standard output (1) |
84 | | - os.open("/dev/null", os.O_RDWR) # standard error (2) |
85 | | - |
86 | | - return(0) |
87 | | - |
88 | 14 | def debug(msg): |
89 | 15 | global debugging |
90 | 16 | if debugging: |
— | — | @@ -177,6 +103,7 @@ |
178 | 104 | |
179 | 105 | # Become a daemon |
180 | 106 | if daemon: |
| 107 | + from util import createDaemon |
181 | 108 | createDaemon() |
182 | 109 | |
183 | 110 | # Open the UDP socket |
Index: trunk/udpmcast/htcpseqcheck.py |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | # |
8 | 8 | # $Id$ |
9 | 9 | |
10 | | -import socket, getopt, sys, os, signal, pwd, grp, struct |
| 10 | +import socket, getopt, sys, pwd, grp, struct |
11 | 11 | |
12 | 12 | from datetime import datetime, timedelta |
13 | 13 | from collections import deque |
— | — | @@ -94,81 +94,6 @@ |
95 | 95 | |
96 | 96 | self.counts.update(counts) |
97 | 97 | |
98 | | - |
99 | | -def createDaemon(): |
100 | | - """ |
101 | | - Detach a process from the controlling terminal and run it in the |
102 | | - background as a daemon. |
103 | | - """ |
104 | | - |
105 | | - try: |
106 | | - # Fork a child process so the parent can exit. This will return control |
107 | | - # to the command line or shell. This is required so that the new process |
108 | | - # is guaranteed not to be a process group leader. We have this guarantee |
109 | | - # because the process GID of the parent is inherited by the child, but |
110 | | - # the child gets a new PID, making it impossible for its PID to equal its |
111 | | - # PGID. |
112 | | - pid = os.fork() |
113 | | - except OSError, e: |
114 | | - return((e.errno, e.strerror)) # ERROR (return a tuple) |
115 | | - |
116 | | - if (pid == 0): # The first child. |
117 | | - |
118 | | - # Next we call os.setsid() to become the session leader of this new |
119 | | - # session. The process also becomes the process group leader of the |
120 | | - # new process group. Since a controlling terminal is associated with a |
121 | | - # session, and this new session has not yet acquired a controlling |
122 | | - # terminal our process now has no controlling terminal. This shouldn't |
123 | | - # fail, since we're guaranteed that the child is not a process group |
124 | | - # leader. |
125 | | - os.setsid() |
126 | | - |
127 | | - # When the first child terminates, all processes in the second child |
128 | | - # are sent a SIGHUP, so it's ignored. |
129 | | - signal.signal(signal.SIGHUP, signal.SIG_IGN) |
130 | | - |
131 | | - try: |
132 | | - # Fork a second child to prevent zombies. Since the first child is |
133 | | - # a session leader without a controlling terminal, it's possible for |
134 | | - # it to acquire one by opening a terminal in the future. This second |
135 | | - # fork guarantees that the child is no longer a session leader, thus |
136 | | - # preventing the daemon from ever acquiring a controlling terminal. |
137 | | - pid = os.fork() # Fork a second child. |
138 | | - except OSError, e: |
139 | | - return((e.errno, e.strerror)) # ERROR (return a tuple) |
140 | | - |
141 | | - if (pid == 0): # The second child. |
142 | | - # Ensure that the daemon doesn't keep any directory in use. Failure |
143 | | - # to do this could make a filesystem unmountable. |
144 | | - os.chdir("/") |
145 | | - # Give the child complete control over permissions. |
146 | | - os.umask(0) |
147 | | - else: |
148 | | - os._exit(0) # Exit parent (the first child) of the second child. |
149 | | - else: |
150 | | - os._exit(0) # Exit parent of the first child. |
151 | | - |
152 | | - # Close all open files. Try the system configuration variable, SC_OPEN_MAX, |
153 | | - # for the maximum number of open files to close. If it doesn't exist, use |
154 | | - # the default value (configurable). |
155 | | - try: |
156 | | - maxfd = os.sysconf("SC_OPEN_MAX") |
157 | | - except (AttributeError, ValueError): |
158 | | - maxfd = 256 # default maximum |
159 | | - |
160 | | - for fd in range(0, maxfd): |
161 | | - try: |
162 | | - os.close(fd) |
163 | | - except OSError: # ERROR (ignore) |
164 | | - pass |
165 | | - |
166 | | - # Redirect the standard file descriptors to /dev/null. |
167 | | - os.open("/dev/null", os.O_RDONLY) # standard input (0) |
168 | | - os.open("/dev/null", os.O_RDWR) # standard output (1) |
169 | | - os.open("/dev/null", os.O_RDWR) # standard error (2) |
170 | | - |
171 | | - return(0) |
172 | | - |
173 | 98 | def receive_htcp(sock): |
174 | 99 | portnr = sock.getsockname()[1]; |
175 | 100 | |
— | — | @@ -276,6 +201,7 @@ |
277 | 202 | |
278 | 203 | # Become a daemon |
279 | 204 | if daemon: |
| 205 | + from util import createDaemon |
280 | 206 | createDaemon() |
281 | 207 | |
282 | 208 | # Open the UDP socket |