##// END OF EJS Templates
procutil: move protectio/restoreio from commandserver...
Yuya Nishihara -
r37141:0216232f default
parent child Browse files
Show More
@@ -306,35 +306,6 b' class server(object):'
306
306
307 return 0
307 return 0
308
308
309 def _protectio(uin, uout):
310 """Duplicate streams and redirect original to null if (uin, uout) are
311 stdio
312
313 Returns (fin, fout) which point to the original (uin, uout) fds, but
314 may be copy of (uin, uout). The returned streams can be considered
315 "owned" in that print(), exec(), etc. never reach to them.
316 """
317 uout.flush()
318 newfiles = []
319 nullfd = os.open(os.devnull, os.O_RDWR)
320 for f, sysf, mode in [(uin, procutil.stdin, r'rb'),
321 (uout, procutil.stdout, r'wb')]:
322 if f is sysf:
323 newfd = os.dup(f.fileno())
324 os.dup2(nullfd, f.fileno())
325 f = os.fdopen(newfd, mode)
326 newfiles.append(f)
327 os.close(nullfd)
328 return tuple(newfiles)
329
330 def _restoreio(uin, uout, fin, fout):
331 """Restore (uin, uout) streams from possibly duplicated (fin, fout)"""
332 uout.flush()
333 for f, uif in [(fin, uin), (fout, uout)]:
334 if f is not uif:
335 os.dup2(f.fileno(), uif.fileno())
336 f.close()
337
338 class pipeservice(object):
309 class pipeservice(object):
339 def __init__(self, ui, repo, opts):
310 def __init__(self, ui, repo, opts):
340 self.ui = ui
311 self.ui = ui
@@ -347,13 +318,13 b' class pipeservice(object):'
347 ui = self.ui
318 ui = self.ui
348 # redirect stdio to null device so that broken extensions or in-process
319 # redirect stdio to null device so that broken extensions or in-process
349 # hooks will never cause corruption of channel protocol.
320 # hooks will never cause corruption of channel protocol.
350 fin, fout = _protectio(ui.fin, ui.fout)
321 fin, fout = procutil.protectstdio(ui.fin, ui.fout)
351 try:
322 try:
352 sv = server(ui, self.repo, fin, fout)
323 sv = server(ui, self.repo, fin, fout)
353 return sv.serve()
324 return sv.serve()
354 finally:
325 finally:
355 sv.cleanup()
326 sv.cleanup()
356 _restoreio(ui.fin, ui.fout, fin, fout)
327 procutil.restorestdio(ui.fin, ui.fout, fin, fout)
357
328
358 def _initworkerprocess():
329 def _initworkerprocess():
359 # use a different process group from the master process, in order to:
330 # use a different process group from the master process, in order to:
@@ -211,6 +211,35 b' def isstdin(f):'
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):
General Comments 0
You need to be logged in to leave comments. Login now