hook: flush stdout before restoring stderr redirection
There was a similar issue to
8b011ededfb2. If an in-process hook writes
to stdout, the data may be buffered. In which case, stdout must be flushed
before restoring its file descriptor. Otherwise, remaining data would be sent
over the ssh wire and corrupts the protocol.
Note that this is a different redirection from the one I've just removed.
--- a/mercurial/hook.py Thu Oct 20 22:39:59 2016 +0900
+++ b/mercurial/hook.py Tue Nov 08 22:22:22 2016 +0900
@@ -258,6 +258,7 @@
sys.stderr.flush()
finally:
if _redirect and oldstdout >= 0:
+ sys.__stdout__.flush() # write hook output to stderr fd
os.dup2(oldstdout, stdoutno)
os.close(oldstdout)
--- a/tests/test-ssh.t Thu Oct 20 22:39:59 2016 +0900
+++ b/tests/test-ssh.t Tue Nov 08 22:22:22 2016 +0900
@@ -265,8 +265,17 @@
> sys.stdout.write("KABOOM\n")
> EOF
- $ echo '[hooks]' >> ../remote/.hg/hgrc
- $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
+ $ cat <<EOF > $TESTTMP/badpyhook.py
+ > import sys
+ > def hook(ui, repo, hooktype, **kwargs):
+ > sys.stdout.write("KABOOM IN PROCESS\n")
+ > EOF
+
+ $ cat <<EOF >> ../remote/.hg/hgrc
+ > [hooks]
+ > changegroup.stdout = python $TESTTMP/badhook
+ > changegroup.pystdout = python:$TESTTMP/badpyhook.py:hook
+ > EOF
$ echo r > r
$ hg ci -A -m z r
@@ -281,6 +290,7 @@
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
remote: KABOOM
+ remote: KABOOM IN PROCESS
$ hg -R ../remote heads
changeset: 5:1383141674ec
tag: tip
@@ -447,6 +457,7 @@
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
remote: KABOOM
+ remote: KABOOM IN PROCESS
local stdout
debug output