comparison 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
comparison
equal deleted inserted replaced
37125:4f742c2cb837 37126:0216232f21ab
209 return _testfileno(f, sys.__stdin__) 209 return _testfileno(f, sys.__stdin__)
210 210
211 def isstdout(f): 211 def isstdout(f):
212 return _testfileno(f, sys.__stdout__) 212 return _testfileno(f, sys.__stdout__)
213 213
214 def protectstdio(uin, uout):
215 """Duplicate streams and redirect original to null if (uin, uout) are
216 stdio
217
218 Returns (fin, fout) which point to the original (uin, uout) fds, but
219 may be copy of (uin, uout). The returned streams can be considered
220 "owned" in that print(), exec(), etc. never reach to them.
221 """
222 uout.flush()
223 newfiles = []
224 nullfd = os.open(os.devnull, os.O_RDWR)
225 for f, sysf, mode in [(uin, stdin, r'rb'),
226 (uout, stdout, r'wb')]:
227 if f is sysf:
228 newfd = os.dup(f.fileno())
229 os.dup2(nullfd, f.fileno())
230 f = os.fdopen(newfd, mode)
231 newfiles.append(f)
232 os.close(nullfd)
233 return tuple(newfiles)
234
235 def restorestdio(uin, uout, fin, fout):
236 """Restore (uin, uout) streams from possibly duplicated (fin, fout)"""
237 uout.flush()
238 for f, uif in [(fin, uin), (fout, uout)]:
239 if f is not uif:
240 os.dup2(f.fileno(), uif.fileno())
241 f.close()
242
214 def shellenviron(environ=None): 243 def shellenviron(environ=None):
215 """return environ with optional override, useful for shelling out""" 244 """return environ with optional override, useful for shelling out"""
216 def py2shell(val): 245 def py2shell(val):
217 'convert python object into string that is useful to shell' 246 'convert python object into string that is useful to shell'
218 if val is None or val is False: 247 if val is None or val is False: