Keep multiplexing until both of the input streams reach EOF, and stop
paying attention to the process status. Leave the process lifetime up
to the caller.
This avoids losing a backtrace, for example if the output stream ends
before the error stream.
Thanks to Johannes Berg for help fixing some issues in previous
versions.
Signed-off-by: Rob Browning <
r...@defaultvalue.org>
Tested-by: Rob Browning <
r...@defaultvalue.org>
---
lib/bup/cmd/mux.py | 2 +-
lib/bup/helpers.py | 16 ++++++++++------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/lib/bup/cmd/mux.py b/lib/bup/cmd/mux.py
index 1ae43603..9d7ddea5 100644
--- a/lib/bup/cmd/mux.py
+++ b/lib/bup/cmd/mux.py
@@ -43,7 +43,7 @@ def main(argv):
out = byte_stream(sys.stdout)
out.write(b'BUPMUX')
out.flush()
- mux(p, out.fileno(), outr, errr)
+ mux(out.fileno(), outr, errr)
os.close(outr)
os.close(errr)
prv = p.wait()
diff --git a/lib/bup/helpers.py b/lib/bup/helpers.py
index e7c56e15..bc36e19f 100644
--- a/lib/bup/helpers.py
+++ b/lib/bup/helpers.py
@@ -524,20 +524,24 @@ def checked_reader(fd, n):
MAX_PACKET = 128 * 1024
-def mux(p, outfd, outr, errr):
+def mux(outfd, outr, errr):
try:
fds = [outr, errr]
- while p.poll() is None:
+ while fds:
rl, _, _ = select.select(fds, [], [])
for fd in rl:
if fd == outr:
buf = os.read(outr, MAX_PACKET)
- if not buf: break
- os.writev(outfd, (struct.pack('!IB', len(buf), 1), buf))
+ if not buf:
+ fds.remove(outr)
+ else:
+ os.writev(outfd, (struct.pack('!IB', len(buf), 1), buf))
elif fd == errr:
buf = os.read(errr, 1024)
- if not buf: break
- os.writev(outfd, (struct.pack('!IB', len(buf), 2), buf))
+ if not buf:
+ fds.remove(errr)
+ else:
+ os.writev(outfd, (struct.pack('!IB', len(buf), 2), buf))
finally:
os.write(outfd, struct.pack('!IB', 0, 3))
--
2.47.3