437 return |
437 return |
438 nullfd = os.open(os.devnull, os.O_WRONLY) |
438 nullfd = os.open(os.devnull, os.O_WRONLY) |
439 ui = self.ui |
439 ui = self.ui |
440 for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels): |
440 for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels): |
441 newfp = getattr(ui, fn) |
441 newfp = getattr(ui, fn) |
442 # On Python 2, newfp and fp may be separate file objects associated |
442 # On Python 3, newfp is just a wrapper around fp even if newfp is |
443 # with the same fd, so we must close newfp while it's associated |
443 # not fp, so deleting newfp is safe. |
444 # with the client. Otherwise the new associated fd would be closed |
444 if newfp is not fp: |
445 # when newfp gets deleted. On Python 3, newfp is just a wrapper |
|
446 # around fp even if newfp is not fp, so deleting newfp is safe. |
|
447 if not (pycompat.ispy3 or newfp is fp): |
|
448 newfp.close() |
445 newfp.close() |
449 # restore original fd: fp is open again |
446 # restore original fd: fp is open again |
450 try: |
447 try: |
451 if (pycompat.ispy3 or newfp is fp) and 'w' in mode: |
448 if newfp is fp and 'w' in mode: |
452 # Discard buffered data which couldn't be flushed because |
449 # Discard buffered data which couldn't be flushed because |
453 # of EPIPE. The data should belong to the current session |
450 # of EPIPE. The data should belong to the current session |
454 # and should never persist. |
451 # and should never persist. |
455 os.dup2(nullfd, fp.fileno()) |
452 os.dup2(nullfd, fp.fileno()) |
456 fp.flush() |
453 fp.flush() |