Mercurial > public > mercurial-scm > hg-stable
diff mercurial/utils/procutil.py @ 37126:0216232f21ab
procutil: move protectio/restoreio from commandserver
Some variants of this will be useful for stdio-based servers such as
sshserver.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 25 Mar 2018 11:40:30 +0900 |
parents | 5be286db5fb5 |
children | 6715e8035b4f |
line wrap: on
line diff
--- a/mercurial/utils/procutil.py Sun Mar 25 11:30:59 2018 +0900 +++ b/mercurial/utils/procutil.py Sun Mar 25 11:40:30 2018 +0900 @@ -211,6 +211,35 @@ def isstdout(f): return _testfileno(f, sys.__stdout__) +def protectstdio(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 [(uin, stdin, r'rb'), + (uout, stdout, r'wb')]: + if f is sysf: + newfd = os.dup(f.fileno()) + os.dup2(nullfd, f.fileno()) + f = os.fdopen(newfd, mode) + newfiles.append(f) + os.close(nullfd) + return tuple(newfiles) + +def restorestdio(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() + def shellenviron(environ=None): """return environ with optional override, useful for shelling out""" def py2shell(val):