|
6 | 6 | import json |
7 | 7 | import os |
8 | 8 | import pathlib |
| 9 | +import select |
9 | 10 | import socket |
10 | 11 | import subprocess |
11 | 12 | import sys |
@@ -182,18 +183,29 @@ def pipe_setup_and_listen(pipe_name: str, result: List[str]): |
182 | 183 | completed = threading.Event() |
183 | 184 |
|
184 | 185 | def listen(): |
185 | | - # Open the FIFO for reading |
186 | | - with pipe_path.open() as fifo: |
187 | | - print("Waiting for data...") |
| 186 | + # When using blocking IO, open blocks forever if the subprocess compleates but never |
| 187 | + # opens the pipe for writing (which may happen if there is an error early in the |
| 188 | + # subprocess.) Hence we go to the effort of using non-blocking io so that we can |
| 189 | + # break out of this function if that happens. |
| 190 | + fd = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK) |
| 191 | + try: |
| 192 | + all_data = bytearray() |
188 | 193 | while True: |
189 | 194 | if completed.is_set(): |
190 | | - break # Exit loop if completed event is set |
191 | | - data = fifo.read() # This will block until data is available |
192 | | - if len(data) == 0: |
193 | | - # If data is empty, assume EOF |
194 | 195 | break |
195 | | - print(f"Received: {data}") |
196 | | - result.append(data) |
| 196 | + |
| 197 | + # Wait till the pipe has data to read, with a timeout. |
| 198 | + rlist, _, _ = select.select([fd], [], [], 0.1) |
| 199 | + if rlist: |
| 200 | + # Data is available, read it. |
| 201 | + data = os.read(fd, 1024) |
| 202 | + if not data: |
| 203 | + # Empty data indicates EOF. |
| 204 | + break |
| 205 | + all_data.extend(data) |
| 206 | + result.append(all_data.decode()) |
| 207 | + finally: |
| 208 | + os.close(fd) |
197 | 209 |
|
198 | 210 | thread = threading.Thread(target=listen) |
199 | 211 | thread.start() |
|
0 commit comments