OLD | NEW |
1 #!/usr/bin/python2.4 | 1 #!/usr/bin/python2.4 |
2 # | 2 # |
3 # | 3 # |
4 # Copyright 2007, The Android Open Source Project | 4 # Copyright 2007, The Android Open Source Project |
5 # | 5 # |
6 # Licensed under the Apache License, Version 2.0 (the "License"); | 6 # Licensed under the Apache License, Version 2.0 (the "License"); |
7 # you may not use this file except in compliance with the License. | 7 # you may not use this file except in compliance with the License. |
8 # You may obtain a copy of the License at | 8 # You may obtain a copy of the License at |
9 # | 9 # |
10 # http://www.apache.org/licenses/LICENSE-2.0 | 10 # http://www.apache.org/licenses/LICENSE-2.0 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 stdin_input: data to feed to stdin | 73 stdin_input: data to feed to stdin |
74 Returns: | 74 Returns: |
75 output of command | 75 output of command |
76 Raises: | 76 Raises: |
77 errors.WaitForResponseTimedOutError if command did not complete within | 77 errors.WaitForResponseTimedOutError if command did not complete within |
78 timeout_time seconds. | 78 timeout_time seconds. |
79 errors.AbortError is command returned error code and SetAbortOnError is on. | 79 errors.AbortError is command returned error code and SetAbortOnError is on. |
80 """ | 80 """ |
81 start_time = time.time() | 81 start_time = time.time() |
82 so = [] | 82 so = [] |
83 pid = [] | |
84 global _abort_on_error, error_occurred | 83 global _abort_on_error, error_occurred |
85 error_occurred = False | 84 error_occurred = False |
86 | 85 |
| 86 if return_output: |
| 87 output_dest = subprocess.PIPE |
| 88 else: |
| 89 # None means direct to stdout |
| 90 output_dest = None |
| 91 if stdin_input: |
| 92 stdin_dest = subprocess.PIPE |
| 93 else: |
| 94 stdin_dest = None |
| 95 pipe = subprocess.Popen( |
| 96 cmd, |
| 97 executable='/bin/bash', |
| 98 stdin=stdin_dest, |
| 99 stdout=output_dest, |
| 100 stderr=subprocess.STDOUT, |
| 101 shell=True) |
| 102 |
87 def Run(): | 103 def Run(): |
88 global error_occurred | 104 global error_occurred |
89 if return_output: | |
90 output_dest = subprocess.PIPE | |
91 else: | |
92 # None means direct to stdout | |
93 output_dest = None | |
94 if stdin_input: | |
95 stdin_dest = subprocess.PIPE | |
96 else: | |
97 stdin_dest = None | |
98 pipe = subprocess.Popen( | |
99 cmd, | |
100 executable='/bin/bash', | |
101 stdin=stdin_dest, | |
102 stdout=output_dest, | |
103 stderr=subprocess.STDOUT, | |
104 shell=True) | |
105 pid.append(pipe.pid) | |
106 try: | 105 try: |
107 output = pipe.communicate(input=stdin_input)[0] | 106 output = pipe.communicate(input=stdin_input)[0] |
108 if output is not None and len(output) > 0: | 107 if output is not None and len(output) > 0: |
109 so.append(output) | 108 so.append(output) |
110 except OSError, e: | 109 except OSError, e: |
111 logger.SilentLog("failed to retrieve stdout from: %s" % cmd) | 110 logger.SilentLog("failed to retrieve stdout from: %s" % cmd) |
112 logger.Log(e) | 111 logger.Log(e) |
113 so.append("ERROR") | 112 so.append("ERROR") |
114 error_occurred = True | 113 error_occurred = True |
115 if pipe.returncode: | 114 if pipe.returncode: |
116 logger.SilentLog("Error: %s returned %d error code" %(cmd, | 115 logger.SilentLog("Error: %s returned %d error code" %(cmd, |
117 pipe.returncode)) | 116 pipe.returncode)) |
118 error_occurred = True | 117 error_occurred = True |
119 | 118 |
120 t = threading.Thread(target=Run) | 119 t = threading.Thread(target=Run) |
121 t.start() | 120 t.start() |
122 | 121 t.join(timeout_time) |
123 break_loop = False | 122 if t.isAlive(): |
124 while not break_loop: | 123 try: |
125 if not t.isAlive(): | 124 pipe.kill() |
126 break_loop = True | 125 except OSError: |
127 | 126 # Can't kill a dead process. |
128 # Check the timeout | 127 pass |
129 if (not break_loop and timeout_time is not None | 128 finally: |
130 and time.time() > start_time + timeout_time): | |
131 try: | |
132 os.kill(pid[0], signal.SIGKILL) | |
133 except OSError: | |
134 # process already dead. No action required. | |
135 pass | |
136 | |
137 logger.SilentLog("about to raise a timeout for: %s" % cmd) | 129 logger.SilentLog("about to raise a timeout for: %s" % cmd) |
138 raise errors.WaitForResponseTimedOutError | 130 raise errors.WaitForResponseTimedOutError |
139 if not break_loop: | |
140 time.sleep(0.1) | |
141 | 131 |
142 t.join() | |
143 output = "".join(so) | 132 output = "".join(so) |
144 if _abort_on_error and error_occurred: | 133 if _abort_on_error and error_occurred: |
145 raise errors.AbortError(msg=output) | 134 raise errors.AbortError(msg=output) |
146 | 135 |
147 return "".join(so) | 136 return "".join(so) |
148 | 137 |
149 | 138 |
150 def RunHostCommand(binary, valgrind=False): | 139 def RunHostCommand(binary, valgrind=False): |
151 """Run a command on the host (opt using valgrind). | 140 """Run a command on the host (opt using valgrind). |
152 | 141 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 def HasValgrind(): | 176 def HasValgrind(): |
188 """Check that /usr/bin/valgrind exists. | 177 """Check that /usr/bin/valgrind exists. |
189 | 178 |
190 We look for the fullpath to avoid picking up 'alternative' valgrind | 179 We look for the fullpath to avoid picking up 'alternative' valgrind |
191 on the system. | 180 on the system. |
192 | 181 |
193 Returns: | 182 Returns: |
194 True if a system valgrind was found. | 183 True if a system valgrind was found. |
195 """ | 184 """ |
196 return os.path.exists("/usr/bin/valgrind") | 185 return os.path.exists("/usr/bin/valgrind") |
OLD | NEW |