Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 6429 | ||||||||
Proposed branch: | lp:~ptman/hipl/reload | ||||||||
Merge into: | lp:hipl | ||||||||
Diff against target: |
394 lines (+85/-73) 6 files modified
debian/hipl-dnsproxy.install.in (+1/-0) debian/resolvconf/hipdnsproxy (+2/-0) tools/hipdnsproxy/DNS/Type.py (+1/-0) tools/hipdnsproxy/dnsproxy.py (+43/-37) tools/hipdnsproxy/resolvconf.py (+20/-10) tools/hipdnsproxy/util.py (+18/-26) |
||||||||
To merge this branch: | bzr merge lp:~ptman/hipl/reload | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Miika Komu | Approve | ||
Review via email: mp+178932@code.launchpad.net |
Commit message
Description of the change
Implement sane SIGHUP handling (reload configs)
Fixes #1132042 and #1189371
To post a comment you must log in.
lp:~ptman/hipl/reload
updated
- 6425. By Paul Tötterman
-
Retry in case of EINTR
- 6426. By Paul Tötterman
-
Merge trunk
- 6427. By Paul Tötterman
-
Merged trunk
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/hipl-dnsproxy.install.in' | |||
2 | --- debian/hipl-dnsproxy.install.in 2011-02-08 17:55:52 +0000 | |||
3 | +++ debian/hipl-dnsproxy.install.in 2013-08-12 13:20:15 +0000 | |||
4 | @@ -3,3 +3,4 @@ | |||
5 | 3 | debian/tmp/@pythondir@/DNS @pythondir@ | 3 | debian/tmp/@pythondir@/DNS @pythondir@ |
6 | 4 | debian/tmp/@pythondir@/hipdnskeyparse @pythondir@ | 4 | debian/tmp/@pythondir@/hipdnskeyparse @pythondir@ |
7 | 5 | debian/tmp/@pythondir@/hipdnsproxy @pythondir@ | 5 | debian/tmp/@pythondir@/hipdnsproxy @pythondir@ |
8 | 6 | debian/resolvconf/hipdnsproxy etc/resolvconf/update.d | ||
9 | 6 | 7 | ||
10 | === added directory 'debian/resolvconf' | |||
11 | === added file 'debian/resolvconf/hipdnsproxy' | |||
12 | --- debian/resolvconf/hipdnsproxy 1970-01-01 00:00:00 +0000 | |||
13 | +++ debian/resolvconf/hipdnsproxy 2013-08-12 13:20:15 +0000 | |||
14 | @@ -0,0 +1,2 @@ | |||
15 | 1 | #!/bin/sh | ||
16 | 2 | /bin/kill -HUP `/usr/bin/head -1 /var/run/hipdnsproxy.pid` > /dev/null 2>&1 | ||
17 | 0 | 3 | ||
18 | === modified file 'tools/hipdnsproxy/DNS/Type.py' | |||
19 | --- tools/hipdnsproxy/DNS/Type.py 2010-02-18 16:45:11 +0000 | |||
20 | +++ tools/hipdnsproxy/DNS/Type.py 2013-08-12 13:20:15 +0000 | |||
21 | @@ -28,6 +28,7 @@ | |||
22 | 28 | TXT = 16 # text strings | 28 | TXT = 16 # text strings |
23 | 29 | AAAA = 28 # IPv6 AAAA records (RFC 1886) | 29 | AAAA = 28 # IPv6 AAAA records (RFC 1886) |
24 | 30 | SRV = 33 # DNS RR for specifying the location of services (RFC 2782) | 30 | SRV = 33 # DNS RR for specifying the location of services (RFC 2782) |
25 | 31 | HIP = 55 # Host Identity Protocol (RFC 5205) | ||
26 | 31 | 32 | ||
27 | 32 | 33 | ||
28 | 33 | # Additional TYPE values from host.c source | 34 | # Additional TYPE values from host.c source |
29 | 34 | 35 | ||
30 | === modified file 'tools/hipdnsproxy/dnsproxy.py' | |||
31 | --- tools/hipdnsproxy/dnsproxy.py 2013-05-26 15:29:43 +0000 | |||
32 | +++ tools/hipdnsproxy/dnsproxy.py 2013-08-12 13:20:15 +0000 | |||
33 | @@ -82,7 +82,7 @@ | |||
34 | 82 | import hosts | 82 | import hosts |
35 | 83 | import resolvconf | 83 | import resolvconf |
36 | 84 | import util | 84 | import util |
38 | 85 | from DNS import Serialize, DeSerialize | 85 | from DNS import Serialize, DeSerialize, Type |
39 | 86 | 86 | ||
40 | 87 | 87 | ||
41 | 88 | DEFAULT_HOSTS = '/etc/hosts' | 88 | DEFAULT_HOSTS = '/etc/hosts' |
42 | @@ -167,7 +167,6 @@ | |||
43 | 167 | self.server_port = server_port | 167 | self.server_port = server_port |
44 | 168 | 168 | ||
45 | 169 | self.resolvconf = resolvconf.ResolvConf() | 169 | self.resolvconf = resolvconf.ResolvConf() |
46 | 170 | self.resolvconf.parse() | ||
47 | 171 | 170 | ||
48 | 172 | if self.hostsnames is None: | 171 | if self.hostsnames is None: |
49 | 173 | self.hostsnames = [] | 172 | self.hostsnames = [] |
50 | @@ -218,8 +217,6 @@ | |||
51 | 218 | env = os.environ | 217 | env = os.environ |
52 | 219 | if self.server_ip is None: | 218 | if self.server_ip is None: |
53 | 220 | self.server_ip = env.get('SERVER', None) | 219 | self.server_ip = env.get('SERVER', None) |
54 | 221 | if self.server_ip is None: | ||
55 | 222 | self.server_ip = self.resolvconf.nameserver | ||
56 | 223 | if self.server_port is None: | 220 | if self.server_port is None: |
57 | 224 | server_port = env.get('SERVERPORT', None) | 221 | server_port = env.get('SERVERPORT', None) |
58 | 225 | if server_port is not None: | 222 | if server_port is not None: |
59 | @@ -367,7 +364,7 @@ | |||
60 | 367 | 364 | ||
61 | 368 | # convert 1.2....1.0.0.1.0.0.2.ip6.arpa to a HIT and | 365 | # convert 1.2....1.0.0.1.0.0.2.ip6.arpa to a HIT and |
62 | 369 | # map host name to address from cache | 366 | # map host name to address from cache |
64 | 370 | if qtype == 12: | 367 | if qtype == Type.PTR: |
65 | 371 | lr_ptr = None | 368 | lr_ptr = None |
66 | 372 | addr_str = hosts.ptr_to_addr(qname) | 369 | addr_str = hosts.ptr_to_addr(qname) |
67 | 373 | if (not self.disable_lsi and addr_str is not None and | 370 | if (not self.disable_lsi and addr_str is not None and |
68 | @@ -387,19 +384,19 @@ | |||
69 | 387 | add_hit_ip_map(lr_aaaa_hit[0], lr_a[0]) | 384 | add_hit_ip_map(lr_aaaa_hit[0], lr_a[0]) |
70 | 388 | if lr_aaaa is not None: | 385 | if lr_aaaa is not None: |
71 | 389 | add_hit_ip_map(lr_aaaa_hit[0], lr_aaaa[0]) | 386 | add_hit_ip_map(lr_aaaa_hit[0], lr_aaaa[0]) |
73 | 390 | if qtype == 28: # 28: AAAA | 387 | if qtype == Type.AAAA: |
74 | 391 | result = lr_aaaa_hit | 388 | result = lr_aaaa_hit |
76 | 392 | elif qtype == 1 and not self.disable_lsi: # 1: A | 389 | elif qtype == Type.A and not self.disable_lsi: |
77 | 393 | lsi = hit_to_lsi(lr_aaaa_hit[0]) | 390 | lsi = hit_to_lsi(lr_aaaa_hit[0]) |
78 | 394 | if lsi is not None: | 391 | if lsi is not None: |
79 | 395 | result = (lsi, lr_aaaa_hit[1]) | 392 | result = (lsi, lr_aaaa_hit[1]) |
80 | 396 | elif self.prefix and packet['questions'][0][0].startswith(self.prefix): | 393 | elif self.prefix and packet['questions'][0][0].startswith(self.prefix): |
81 | 397 | result = None | 394 | result = None |
83 | 398 | elif qtype == 28: | 395 | elif qtype == Type.AAAA: |
84 | 399 | result = lr_aaaa | 396 | result = lr_aaaa |
86 | 400 | elif qtype == 1: | 397 | elif qtype == Type.A: |
87 | 401 | result = lr_a | 398 | result = lr_a |
89 | 402 | elif qtype == 12 and lr_ptr is not None: # 12: PTR | 399 | elif qtype == Type.PTR and lr_ptr is not None: |
90 | 403 | result = (lr_ptr, self.hosts_ttl) | 400 | result = (lr_ptr, self.hosts_ttl) |
91 | 404 | 401 | ||
92 | 405 | if result is not None: | 402 | if result is not None: |
93 | @@ -418,7 +415,7 @@ | |||
94 | 418 | 415 | ||
95 | 419 | dns_hit_found = False | 416 | dns_hit_found = False |
96 | 420 | for answer in packet['answers']: | 417 | for answer in packet['answers']: |
98 | 421 | if answer[1] == 55: | 418 | if answer[1] == Type.HIP: |
99 | 422 | dns_hit_found = True | 419 | dns_hit_found = True |
100 | 423 | break | 420 | break |
101 | 424 | 421 | ||
102 | @@ -429,20 +426,20 @@ | |||
103 | 429 | lsi_ans = [] | 426 | lsi_ans = [] |
104 | 430 | 427 | ||
105 | 431 | for answer in packet['answers']: | 428 | for answer in packet['answers']: |
107 | 432 | if answer[1] != 55: | 429 | if answer[1] != Type.HIP: |
108 | 433 | continue | 430 | continue |
109 | 434 | 431 | ||
110 | 435 | hit = socket.inet_ntop(socket.AF_INET6, answer[7]) | 432 | hit = socket.inet_ntop(socket.AF_INET6, answer[7]) |
112 | 436 | hit_ans.append([qname, 28, 1, answer[3], hit]) | 433 | hit_ans.append([qname, Type.AAAA, 1, answer[3], hit]) |
113 | 437 | 434 | ||
115 | 438 | if qtype == 1 and not self.disable_lsi: | 435 | if qtype == Type.A and not self.disable_lsi: |
116 | 439 | lsi = hit_to_lsi(hit) | 436 | lsi = hit_to_lsi(hit) |
117 | 440 | if lsi is not None: | 437 | if lsi is not None: |
118 | 441 | lsi_ans.append([qname, 1, 1, self.hosts_ttl, lsi]) | 438 | lsi_ans.append([qname, 1, 1, self.hosts_ttl, lsi]) |
119 | 442 | 439 | ||
120 | 443 | self.cache_name(qname, hit, answer[3]) | 440 | self.cache_name(qname, hit, answer[3]) |
121 | 444 | 441 | ||
123 | 445 | if qtype == 28 and hit_found: | 442 | if qtype == Type.AAAA and hit_found: |
124 | 446 | packet['answers'] = hit_ans | 443 | packet['answers'] = hit_ans |
125 | 447 | elif lsi is not None: | 444 | elif lsi is not None: |
126 | 448 | packet['answers'] = lsi_ans | 445 | packet['answers'] = lsi_ans |
127 | @@ -459,10 +456,6 @@ | |||
128 | 459 | 456 | ||
129 | 460 | self.parameter_defaults() | 457 | self.parameter_defaults() |
130 | 461 | 458 | ||
131 | 462 | if self.server_ip is None: | ||
132 | 463 | logging.critical('No upstream DNS server, exiting...') | ||
133 | 464 | return | ||
134 | 465 | |||
135 | 466 | # Default virtual interface and address for dnsproxy to | 459 | # Default virtual interface and address for dnsproxy to |
136 | 467 | # avoid problems with other dns forwarders (e.g. dnsmasq) | 460 | # avoid problems with other dns forwarders (e.g. dnsmasq) |
137 | 468 | os.system('ifconfig lo:53 %s' % (self.bind_ip,)) | 461 | os.system('ifconfig lo:53 %s' % (self.bind_ip,)) |
138 | @@ -475,7 +468,6 @@ | |||
139 | 475 | self.bind_port) | 468 | self.bind_port) |
140 | 476 | return | 469 | return |
141 | 477 | 470 | ||
142 | 478 | self.resolvconf.nameserver = self.bind_ip | ||
143 | 479 | 471 | ||
144 | 480 | servsock.settimeout(self.app_timeout) | 472 | servsock.settimeout(self.app_timeout) |
145 | 481 | 473 | ||
146 | @@ -494,10 +486,20 @@ | |||
147 | 494 | 486 | ||
148 | 495 | query_id = 1 | 487 | query_id = 1 |
149 | 496 | 488 | ||
152 | 497 | util.init_wantdown() | 489 | util.init_wantdown() # Initialize signal handler for shutdown |
153 | 498 | util.init_wantdown_int() # Keyboard interrupts | 490 | util.init_hup() # Initialize signal handler for reload |
154 | 499 | 491 | ||
155 | 500 | while not util.wantdown(): | 492 | while not util.wantdown(): |
156 | 493 | self.resolvconf.parse() | ||
157 | 494 | |||
158 | 495 | if self.server_ip is None: | ||
159 | 496 | self.server_ip = self.resolvconf.nameserver | ||
160 | 497 | |||
161 | 498 | if util.wanthup(): | ||
162 | 499 | logging.info('Received SIGHUP. Picking %s as new upstream ' | ||
163 | 500 | 'DNS server', self.server_ip) | ||
164 | 501 | util.wanthup(False) | ||
165 | 502 | |||
166 | 501 | logging.info('Connecting to upstream DNS server...') | 503 | logging.info('Connecting to upstream DNS server...') |
167 | 502 | if ':' not in self.server_ip: | 504 | if ':' not in self.server_ip: |
168 | 503 | server_family = socket.AF_INET | 505 | server_family = socket.AF_INET |
169 | @@ -509,12 +511,13 @@ | |||
170 | 509 | clisock.connect((self.server_ip, self.server_port)) | 511 | clisock.connect((self.server_ip, self.server_port)) |
171 | 510 | connected = True | 512 | connected = True |
172 | 511 | logging.debug('... connected!') | 513 | logging.debug('... connected!') |
173 | 514 | self.resolvconf.nameserver = self.bind_ip | ||
174 | 512 | except socket.error: | 515 | except socket.error: |
175 | 513 | logging.error('Connecting to upstream DNS server failed!') | 516 | logging.error('Connecting to upstream DNS server failed!') |
176 | 514 | time.sleep(3) | 517 | time.sleep(3) |
177 | 515 | connected = False | 518 | connected = False |
178 | 516 | 519 | ||
180 | 517 | while connected and (not util.wantdown()): | 520 | while connected and (not util.wantdown()) and (not util.wanthup()): |
181 | 518 | try: | 521 | try: |
182 | 519 | self.hosts_recheck() | 522 | self.hosts_recheck() |
183 | 520 | 523 | ||
184 | @@ -532,7 +535,7 @@ | |||
185 | 532 | 535 | ||
186 | 533 | sent_answer = False | 536 | sent_answer = False |
187 | 534 | 537 | ||
189 | 535 | if qtype in (1, 28, 12): | 538 | if qtype in (Type.A, Type.AAAA, Type.PTR): |
190 | 536 | if self.hip_cache_lookup(packet): | 539 | if self.hip_cache_lookup(packet): |
191 | 537 | try: | 540 | try: |
192 | 538 | outbuf = Serialize(packet).get_packet() | 541 | outbuf = Serialize(packet).get_packet() |
193 | @@ -563,21 +566,22 @@ | |||
194 | 563 | query_id = (query_id % 65535) + 1 | 566 | query_id = (query_id % 65535) + 1 |
195 | 564 | pckt = copy.copy(packet) | 567 | pckt = copy.copy(packet) |
196 | 565 | pckt['id'] = query_id | 568 | pckt['id'] = query_id |
200 | 566 | if ((qtype == 28 or | 569 | if ((qtype == Type.AAAA or |
201 | 567 | (qtype == 1 and not self.disable_lsi)) and not | 570 | (qtype == Type.A and |
202 | 568 | is_reverse_hit_query( | 571 | not self.disable_lsi)) and |
203 | 572 | not is_reverse_hit_query( | ||
204 | 569 | packet['questions'][0][0])): | 573 | packet['questions'][0][0])): |
205 | 570 | 574 | ||
206 | 571 | if not self.prefix: | 575 | if not self.prefix: |
208 | 572 | pckt['questions'][0][1] = 55 | 576 | pckt['questions'][0][1] = Type.HIP |
209 | 573 | if (self.prefix and | 577 | if (self.prefix and |
210 | 574 | pckt['questions'][0][0].startswith( | 578 | pckt['questions'][0][0].startswith( |
211 | 575 | self.prefix)): | 579 | self.prefix)): |
212 | 576 | pckt['questions'][0][0] = pckt[ | 580 | pckt['questions'][0][0] = pckt[ |
213 | 577 | 'questions'][0][0][len(self.prefix):] | 581 | 'questions'][0][0][len(self.prefix):] |
215 | 578 | pckt['questions'][0][1] = 55 | 582 | pckt['questions'][0][1] = Type.HIP |
216 | 579 | 583 | ||
218 | 580 | if qtype == 12 and not self.disable_lsi: | 584 | if qtype == Type.PTR and not self.disable_lsi: |
219 | 581 | qname = packet['questions'][0][0] | 585 | qname = packet['questions'][0][0] |
220 | 582 | addr_str = hosts.ptr_to_addr(qname) | 586 | addr_str = hosts.ptr_to_addr(qname) |
221 | 583 | if (addr_str is not None and | 587 | if (addr_str is not None and |
222 | @@ -616,7 +620,8 @@ | |||
223 | 616 | # Replace with the original query id | 620 | # Replace with the original query id |
224 | 617 | packet['id'] = packet_o['id'] | 621 | packet['id'] = packet_o['id'] |
225 | 618 | 622 | ||
227 | 619 | if qtype == 55 and query_o[3] in (1, 28): | 623 | if qtype == Type.HIP and query_o[3] in (Type.A, |
228 | 624 | Type.AAAA): | ||
229 | 620 | # Restore qtype | 625 | # Restore qtype |
230 | 621 | packet['questions'][0][1] = query_o[3] | 626 | packet['questions'][0][1] = query_o[3] |
231 | 622 | self.hip_lookup(packet) | 627 | self.hip_lookup(packet) |
232 | @@ -634,18 +639,18 @@ | |||
233 | 634 | for answer in packet['answers']: | 639 | for answer in packet['answers']: |
234 | 635 | answer[0] = self.prefix + answer[0] | 640 | answer[0] = self.prefix + answer[0] |
235 | 636 | 641 | ||
237 | 637 | elif qtype in (1, 28): | 642 | elif qtype in (Type.A, Type.AAAA): |
238 | 638 | hit = self.getaaaa_hit(qname) | 643 | hit = self.getaaaa_hit(qname) |
239 | 639 | ip6 = self.getaaaa(qname) | 644 | ip6 = self.getaaaa(qname) |
240 | 640 | ip4 = self.geta(qname) | 645 | ip4 = self.geta(qname) |
241 | 641 | for answer in packet['answers']: | 646 | for answer in packet['answers']: |
243 | 642 | if answer[1] in (1, 28): | 647 | if answer[1] in (Type.A, Type.AAAA): |
244 | 643 | self.cache_name(qname, answer[4], | 648 | self.cache_name(qname, answer[4], |
245 | 644 | answer[3]) | 649 | answer[3]) |
246 | 645 | if hit is not None: | 650 | if hit is not None: |
247 | 646 | for answer in packet['answers']: | 651 | for answer in packet['answers']: |
250 | 647 | if (answer[1] == 1 or | 652 | if (answer[1] == Type.A or |
251 | 648 | (answer[1] == 28 and not | 653 | (answer[1] == Type.AAAA and not |
252 | 649 | hosts.valid_hit(answer[4]))): | 654 | hosts.valid_hit(answer[4]))): |
253 | 650 | add_hit_ip_map(hit[0], answer[4]) | 655 | add_hit_ip_map(hit[0], answer[4]) |
254 | 651 | # Reply with HIT/LSI once it's been mapped | 656 | # Reply with HIT/LSI once it's been mapped |
255 | @@ -675,14 +680,15 @@ | |||
256 | 675 | # IP was queried for cache only | 680 | # IP was queried for cache only |
257 | 676 | send_reply = False | 681 | send_reply = False |
258 | 677 | 682 | ||
260 | 678 | elif qtype == 12 and isinstance(query_o[3], str): | 683 | elif qtype == Type.PTR and isinstance(query_o[3], |
261 | 684 | str): | ||
262 | 679 | packet['questions'][0][0] = query_o[3] | 685 | packet['questions'][0][0] = query_o[3] |
263 | 680 | for answer in packet['answers']: | 686 | for answer in packet['answers']: |
264 | 681 | answer[0] = query_o[3] | 687 | answer[0] = query_o[3] |
265 | 682 | 688 | ||
266 | 683 | if query_again: | 689 | if query_again: |
267 | 684 | if hit_found: | 690 | if hit_found: |
269 | 685 | qtypes = [28, 1] | 691 | qtypes = [Type.AAAA, Type.A] |
270 | 686 | pckt = copy.deepcopy(packet) | 692 | pckt = copy.deepcopy(packet) |
271 | 687 | else: | 693 | else: |
272 | 688 | qtypes = [query_o[3]] | 694 | qtypes = [query_o[3]] |
273 | 689 | 695 | ||
274 | === modified file 'tools/hipdnsproxy/resolvconf.py' | |||
275 | --- tools/hipdnsproxy/resolvconf.py 2013-05-26 15:28:42 +0000 | |||
276 | +++ tools/hipdnsproxy/resolvconf.py 2013-08-12 13:20:15 +0000 | |||
277 | @@ -26,6 +26,7 @@ | |||
278 | 26 | """Handler for resolv.conf, including resolvconf(8).""" | 26 | """Handler for resolv.conf, including resolvconf(8).""" |
279 | 27 | 27 | ||
280 | 28 | import collections | 28 | import collections |
281 | 29 | import errno | ||
282 | 29 | import logging | 30 | import logging |
283 | 30 | import os | 31 | import os |
284 | 31 | import subprocess | 32 | import subprocess |
285 | @@ -112,16 +113,25 @@ | |||
286 | 112 | 113 | ||
287 | 113 | @classmethod | 114 | @classmethod |
288 | 114 | def fragments(cls): | 115 | def fragments(cls): |
299 | 115 | proc = subprocess.Popen([ResolvConf.LIST_RECORDS], | 116 | """Return list of resolvconf fragments.""" |
300 | 116 | cwd=ResolvConf.FRAGMENT_DIR, stdout=subprocess.PIPE) | 117 | retries = 3 |
301 | 117 | 118 | while retries > 0: | |
302 | 118 | out = proc.stdout.readlines() | 119 | try: |
303 | 119 | proc.communicate() | 120 | proc = subprocess.Popen([ResolvConf.LIST_RECORDS], |
304 | 120 | proc.wait() | 121 | cwd=ResolvConf.FRAGMENT_DIR, stdout=subprocess.PIPE) |
305 | 121 | 122 | ||
306 | 122 | frags = [x.strip() for x in out] | 123 | out = proc.stdout.readlines() |
307 | 123 | 124 | proc.communicate() | |
308 | 124 | return [os.path.join(ResolvConf.FRAGMENT_DIR, x) for x in frags] | 125 | proc.wait() |
309 | 126 | |||
310 | 127 | frags = [x.strip() for x in out] | ||
311 | 128 | |||
312 | 129 | return [os.path.join(ResolvConf.FRAGMENT_DIR, x) for x in frags] | ||
313 | 130 | except IOError, ioe: | ||
314 | 131 | if ioe.errno != errno.EINTR: | ||
315 | 132 | raise | ||
316 | 133 | retries -= 1 | ||
317 | 134 | |||
318 | 125 | 135 | ||
319 | 126 | @classmethod | 136 | @classmethod |
320 | 127 | def resolvconf_add(cls, ifile): | 137 | def resolvconf_add(cls, ifile): |
321 | 128 | 138 | ||
322 | === modified file 'tools/hipdnsproxy/util.py' | |||
323 | --- tools/hipdnsproxy/util.py 2013-02-22 15:16:12 +0000 | |||
324 | +++ tools/hipdnsproxy/util.py 2013-08-12 13:20:15 +0000 | |||
325 | @@ -32,8 +32,7 @@ | |||
326 | 32 | import struct | 32 | import struct |
327 | 33 | import sys | 33 | import sys |
328 | 34 | 34 | ||
331 | 35 | __FLAGS = {'down': False, | 35 | __FLAGS = {'down': False, 'hup': False} |
330 | 36 | 'alarm': False} | ||
332 | 37 | 36 | ||
333 | 38 | 37 | ||
334 | 39 | class Random: | 38 | class Random: |
335 | @@ -67,42 +66,35 @@ | |||
336 | 67 | 66 | ||
337 | 68 | def sighandler(signum, unused_frame): | 67 | def sighandler(signum, unused_frame): |
338 | 69 | """A signal handler that toggles flags about received signals.""" | 68 | """A signal handler that toggles flags about received signals.""" |
345 | 70 | if signum == signal.SIGTERM: | 69 | if signum in (signal.SIGTERM, signal.SIGINT): |
346 | 71 | __FLAGS['down'] = True | 70 | __FLAGS['down'] = True |
347 | 72 | if signum == signal.SIGINT: | 71 | if signum == signal.SIGHUP: |
348 | 73 | __FLAGS['down'] = True | 72 | __FLAGS['hup'] = True |
343 | 74 | if signum == signal.SIGALRM: | ||
344 | 75 | __FLAGS['alarm'] = True | ||
349 | 76 | 73 | ||
350 | 77 | 74 | ||
351 | 78 | def init_wantdown(): | 75 | def init_wantdown(): |
352 | 79 | """Hook signal handler to SIGTERM.""" | 76 | """Hook signal handler to SIGTERM.""" |
353 | 80 | signal.signal(signal.SIGTERM, sighandler) | 77 | signal.signal(signal.SIGTERM, sighandler) |
354 | 81 | |||
355 | 82 | |||
356 | 83 | def init_wantdown_int(): | ||
357 | 84 | """Hook signal handler to SIGINT.""" | ||
358 | 85 | signal.signal(signal.SIGINT, sighandler) | 78 | signal.signal(signal.SIGINT, sighandler) |
359 | 86 | 79 | ||
360 | 87 | 80 | ||
364 | 88 | def init_wantalarm(): | 81 | def init_hup(): |
365 | 89 | """Hook signal handler to SIGALRM.""" | 82 | """Hook signal handler to SIGHUP.""" |
366 | 90 | signal.signal(signal.SIGALRM, sighandler) | 83 | signal.signal(signal.SIGHUP, sighandler) |
367 | 91 | 84 | ||
368 | 92 | 85 | ||
369 | 93 | def wantdown(): | 86 | def wantdown(): |
370 | 94 | """Check if SIGINT or SIGTERM has been received.""" | 87 | """Check if SIGINT or SIGTERM has been received.""" |
382 | 95 | previous = __FLAGS['down'] | 88 | return __FLAGS['down'] |
383 | 96 | __FLAGS['down'] = False | 89 | |
384 | 97 | return previous | 90 | def wanthup(reset=None): |
385 | 98 | 91 | """Check if SIGHUP has been received.""" | |
386 | 99 | 92 | previous = __FLAGS['hup'] | |
387 | 100 | def wantalarm(): | 93 | |
388 | 101 | """Check if SIGALRM has been received.""" | 94 | if reset is not None: |
389 | 102 | previous = __FLAGS['alarm'] | 95 | __FLAGS['hup'] = reset |
390 | 103 | __FLAGS['alarm'] = False | 96 | |
391 | 104 | return previous | 97 | return previous |
381 | 105 | |||
392 | 106 | 98 | ||
393 | 107 | TMULT = ( | 99 | TMULT = ( |
394 | 108 | (re.compile('^(?P<tval>-?\d+(\.\d*))(s|)$', re.I), float, 1), | 100 | (re.compile('^(?P<tval>-?\d+(\.\d*))(s|)$', re.I), float, 1), |
Tested, works. There's still some IOerror left (I'll report this separately), but I think you could fix it directly in the trunk.