--- iutil.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 68 insertions(+), 16 deletions(-) diff --git a/iutil.py b/iutil.py index ba1d0b4..0a4adfa 100644 --- a/iutil.py +++ b/iutil.py @@ -33,6 +33,7 @@ from flags import flags from constants import * from rhpl.translate import _ import re +import select import logging log = logging.getLogger("anaconda") @@ -81,37 +82,88 @@ def execWithRedirect(command, argv, stdin = None, stdout = None, runningLog = open("/tmp/program.log", "a") runningLog.write("Running... %s\n" % ([command] + argv,)) + + #prepare os pipes for feeding tee proceses + pstdout, pstdin = os.pipe() + perrout, perrin = os.pipe() env = os.environ.copy() env.update({"LC_ALL": "C"}) + #prepare "empty" tee proceses so we can properly detect errors + proc_std = None + proc_err = None + try: - proc = subprocess.Popen([command] + argv, stdin=stdin, - stdout=subprocess.PIPE, + #create output pipes with logging (it needs to be different process to avoid deadlock and EOF detection..) + proc_std = subprocess.Popen(["tee", "-a", "/tmp/program.log"], stdin=pstdout, + stdout=stdout, stderr=subprocess.PIPE, + cwd=root, + env=env, bufsize = 1) + + proc_err = subprocess.Popen(["tee", "-a", "/tmp/program.log"], stdin=perrout, + stdout=stderr, + stderr=subprocess.PIPE, + cwd=root, + env=env, bufsize = 1) + + #run the command + proc = subprocess.Popen([command] + argv, stdin=stdin, + stdout=pstdin, + stderr=perrin, preexec_fn=chroot, cwd=root, - env=env) + env=env, bufsize = 1) + + proc.wait() + + #close the output pipes + if proc_std: + proc_std.terminate() + proc_std.wait() + proc_std = None + + if proc_err: + proc_err.terminate() + proc_err.wait() + proc_err = None + + ret = proc.returncode - while True: - (outStr, errStr) = proc.communicate() - if outStr: - os.write(stdout, outStr) - runningLog.write(outStr) - if errStr: - os.write(stderr, errStr) - runningLog.write(errStr) - if proc.returncode is not None: - ret = proc.returncode - break except OSError as e: errstr = "Error running %s: %s" % (command, e.strerror) log.error(errstr) + + #free descriptors + os.close(pstdout) + os.close(perrout) + os.close(pstdin) + os.close(perrin) + + #close the output pipes + if proc_std: + proc_std.terminate() + proc_std.wait() + proc_std = None + + if proc_err: + proc_err.terminate() + proc_err.wait() + proc_err = None + runningLog.write(errstr) runningLog.close() raise RuntimeError, errstr runningLog.close() + + #free descriptors + os.close(pstdout) + os.close(perrout) + os.close(pstdin) + os.close(perrin) + return ret ## Run an external program and capture standard out. -- 1.5.4.3 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list