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 = |
|
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 |
|
|
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