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
104
105
106
107
108
|
# This file is part of Buildbot. Buildbot is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright Buildbot Team Members
# This file contains scripts run by the test_runprocess tests. Note that since
# this code runs in a different Python interpreter, it does not necessarily
# have access to any of the Buildbot source. Functions here should be kept
# very simple!
import sys
import os
import time
import select
import signal
# utils
def write_pidfile(pidfile):
pidfile_tmp = pidfile + "~"
f = open(pidfile_tmp, "w")
f.write(str(os.getpid()))
f.close()
os.rename(pidfile_tmp, pidfile)
def sleep_forever():
signal.alarm(110) # die after 110 seconds
while True:
time.sleep(10)
def wait_for_parent_death():
while True:
ppid = os.getppid()
if ppid == 1:
return
# on some systems, getppid will keep returning
# a dead pid, so check it for liveness
try:
os.kill(ppid, 0)
except OSError: # Probably ENOSUCH
return
script_fns = {}
def script(fn):
script_fns[fn.func_name] = fn
return fn
# scripts
@script
def write_pidfile_and_sleep():
pidfile = sys.argv[2]
write_pidfile(pidfile)
sleep_forever()
@script
def spawn_child():
parent_pidfile, child_pidfile = sys.argv[2:]
if os.fork() == 0:
write_pidfile(child_pidfile)
else:
write_pidfile(parent_pidfile)
sleep_forever()
@script
def double_fork():
# when using a PTY, the child process will get SIGHUP when the
# parent process exits, so ignore that.
signal.signal(signal.SIGHUP, signal.SIG_IGN)
parent_pidfile, child_pidfile = sys.argv[2:]
if os.fork() == 0:
wait_for_parent_death()
write_pidfile(child_pidfile)
sleep_forever()
else:
write_pidfile(parent_pidfile)
sys.exit(0)
@script
def assert_stdin_closed():
# EOF counts as readable data, so we should see stdin in the readable list,
# although it may not appear immediately, and select may return early
bail_at = time.time() + 10
while True:
r, w, x = select.select([0], [], [], 0.01)
if r == [0]: return # succcess!
if time.time() > bail_at:
assert False # failure :(
# make sure this process dies if necessary
if not hasattr(signal, 'alarm'):
signal.alarm = lambda t : None
signal.alarm(110) # die after 110 seconds
# dispatcher
script_fns[sys.argv[1]]()
|