[PATCH 1 of 5] commandserver: rewrite protectio/restoreio to not depend on ui
Yuya Nishihara
yuya at tcha.org
Sun Mar 25 12:54:12 UTC 2018
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1521945059 -32400
# Sun Mar 25 11:30:59 2018 +0900
# Node ID a32a2b99f0627a6acdee3e6e9ff5b677a1cac18d
# Parent 24ab3381bf159f386fec5c205076b67b4ae5a5f6
commandserver: rewrite protectio/restoreio to not depend on ui
Prepares for porting to utils.procutil, in which ui shouldn't be known.
ui.flush() is replaced with ui.fout.flush() since ui.ferr wasn't involved.
diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -306,13 +306,19 @@ class server(object):
return 0
-def _protectio(ui):
- """ duplicates streams and redirect original to null if ui uses stdio """
- ui.flush()
+def _protectio(uin, uout):
+ """Duplicate streams and redirect original to null if (uin, uout) are
+ stdio
+
+ 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()
newfiles = []
nullfd = os.open(os.devnull, os.O_RDWR)
- for f, sysf, mode in [(ui.fin, procutil.stdin, r'rb'),
- (ui.fout, procutil.stdout, r'wb')]:
+ for f, sysf, mode in [(uin, procutil.stdin, r'rb'),
+ (uout, procutil.stdout, r'wb')]:
if f is sysf:
newfd = os.dup(f.fileno())
os.dup2(nullfd, f.fileno())
@@ -321,10 +327,10 @@ def _protectio(ui):
os.close(nullfd)
return tuple(newfiles)
-def _restoreio(ui, fin, fout):
- """ restores streams from duplicated ones """
- ui.flush()
- for f, uif in [(fin, ui.fin), (fout, ui.fout)]:
+def _restoreio(uin, uout, fin, fout):
+ """Restore (uin, uout) streams from possibly duplicated (fin, fout)"""
+ uout.flush()
+ for f, uif in [(fin, uin), (fout, uout)]:
if f is not uif:
os.dup2(f.fileno(), uif.fileno())
f.close()
@@ -341,13 +347,13 @@ class pipeservice(object):
ui = self.ui
# redirect stdio to null device so that broken extensions or in-process
# hooks will never cause corruption of channel protocol.
- fin, fout = _protectio(ui)
+ fin, fout = _protectio(ui.fin, ui.fout)
try:
sv = server(ui, self.repo, fin, fout)
return sv.serve()
finally:
sv.cleanup()
- _restoreio(ui, fin, fout)
+ _restoreio(ui.fin, ui.fout, fin, fout)
def _initworkerprocess():
# use a different process group from the master process, in order to:
More information about the Mercurial-devel
mailing list