Mercurial > hg-stable
changeset 37222:7f78de1c93aa
procutil: redirect ui.fout to stderr while stdio is protected
The new behavior seems slightly nicer as we can at least read the output.
And this is similar to what the sshserver is doing, so we can probably
reuse protectstdio() instead of the weird hook.redirect(True) hack.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 25 Mar 2018 12:15:33 +0900 |
parents | ac71cbad5da3 |
children | 307ee8883975 |
files | mercurial/utils/procutil.py tests/test-commandserver.t |
diffstat | 2 files changed, 12 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/utils/procutil.py Sun Mar 25 12:07:18 2018 +0900 +++ b/mercurial/utils/procutil.py Sun Mar 25 12:15:33 2018 +0900 @@ -213,25 +213,27 @@ return _testfileno(f, sys.__stdout__) def protectstdio(uin, uout): - """Duplicate streams and redirect original to null if (uin, uout) are - stdio + """Duplicate streams and redirect original if (uin, uout) are stdio + + If uin is stdin, it's redirected to /dev/null. If uout is stdout, it's + redirected to stderr so the output is still readable. Returns (fin, fout) which point to the original (uin, uout) fds, but may be copy of (uin, uout). The returned streams can be considered "owned" in that print(), exec(), etc. never reach to them. """ uout.flush() - nullfd = os.open(os.devnull, os.O_RDWR) fin, fout = uin, uout if uin is stdin: newfd = os.dup(uin.fileno()) + nullfd = os.open(os.devnull, os.O_RDONLY) os.dup2(nullfd, uin.fileno()) + os.close(nullfd) fin = os.fdopen(newfd, r'rb') if uout is stdout: newfd = os.dup(uout.fileno()) - os.dup2(nullfd, uout.fileno()) + os.dup2(stderr.fileno(), uout.fileno()) fout = os.fdopen(newfd, r'wb') - os.close(nullfd) return fin, fout def restorestdio(uin, uout, fin, fout):
--- a/tests/test-commandserver.t Sun Mar 25 12:07:18 2018 +0900 +++ b/tests/test-commandserver.t Sun Mar 25 12:15:33 2018 +0900 @@ -249,6 +249,8 @@ ... input=stringio('some input')) *** runcommand --config hooks.pre-identify=python:hook.hook id eff892de26ec tip + hook talking + now try to read something: '' Clean hook cached version $ rm hook.py* @@ -619,7 +621,7 @@ > @command(b"debugwritestdout", norepo=True) > def debugwritestdout(ui): > os.write(1, "low-level stdout fd and\n") - > sys.stdout.write("stdout should be redirected to /dev/null\n") + > sys.stdout.write("stdout should be redirected to stderr\n") > sys.stdout.flush() > EOF $ cat <<EOF >> .hg/hgrc @@ -657,6 +659,8 @@ *** runcommand debugreadstdin read: '' *** runcommand debugwritestdout + low-level stdout fd and + stdout should be redirected to stderr run commandserver in commandserver, which is silly but should work: