Show More
@@ -409,14 +409,23 b' class chgcmdserver(commandserver.server)' | |||||
409 | # be unbuffered no matter if it is a tty or not. |
|
409 | # be unbuffered no matter if it is a tty or not. | |
410 | if fn == b'ferr': |
|
410 | if fn == b'ferr': | |
411 | newfp = fp |
|
411 | newfp = fp | |
|
412 | elif pycompat.ispy3: | |||
|
413 | # On Python 3, the standard library doesn't offer line-buffered | |||
|
414 | # binary streams, so wrap/unwrap it. | |||
|
415 | if fp.isatty(): | |||
|
416 | newfp = procutil.make_line_buffered(fp) | |||
|
417 | else: | |||
|
418 | newfp = procutil.unwrap_line_buffered(fp) | |||
412 | else: |
|
419 | else: | |
413 | # make it line buffered explicitly because the default is |
|
420 | # Python 2 uses the I/O streams provided by the C library, so | |
414 | # decided on first write(), where fout could be a pager. |
|
421 | # make it line-buffered explicitly. Otherwise the default would | |
|
422 | # be decided on first write(), where fout could be a pager. | |||
415 | if fp.isatty(): |
|
423 | if fp.isatty(): | |
416 | bufsize = 1 # line buffered |
|
424 | bufsize = 1 # line buffered | |
417 | else: |
|
425 | else: | |
418 | bufsize = -1 # system default |
|
426 | bufsize = -1 # system default | |
419 | newfp = os.fdopen(fp.fileno(), mode, bufsize) |
|
427 | newfp = os.fdopen(fp.fileno(), mode, bufsize) | |
|
428 | if newfp is not fp: | |||
420 | setattr(ui, fn, newfp) |
|
429 | setattr(ui, fn, newfp) | |
421 | setattr(self, cn, newfp) |
|
430 | setattr(self, cn, newfp) | |
422 |
|
431 | |||
@@ -440,13 +449,16 b' class chgcmdserver(commandserver.server)' | |||||
440 | ui = self.ui |
|
449 | ui = self.ui | |
441 | for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels): |
|
450 | for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels): | |
442 | newfp = getattr(ui, fn) |
|
451 | newfp = getattr(ui, fn) | |
443 | # close newfp while it's associated with client; otherwise it |
|
452 | # On Python 2, newfp and fp may be separate file objects associated | |
444 | # would be closed when newfp is deleted |
|
453 | # with the same fd, so we must close newfp while it's associated | |
445 | if newfp is not fp: |
|
454 | # with the client. Otherwise the new associated fd would be closed | |
|
455 | # when newfp gets deleted. On Python 3, newfp is just a wrapper | |||
|
456 | # around fp even if newfp is not fp, so deleting newfp is safe. | |||
|
457 | if not (pycompat.ispy3 or newfp is fp): | |||
446 | newfp.close() |
|
458 | newfp.close() | |
447 | # restore original fd: fp is open again |
|
459 | # restore original fd: fp is open again | |
448 | try: |
|
460 | try: | |
449 | if newfp is fp and 'w' in mode: |
|
461 | if (pycompat.ispy3 or newfp is fp) and 'w' in mode: | |
450 | # Discard buffered data which couldn't be flushed because |
|
462 | # Discard buffered data which couldn't be flushed because | |
451 | # of EPIPE. The data should belong to the current session |
|
463 | # of EPIPE. The data should belong to the current session | |
452 | # and should never persist. |
|
464 | # and should never persist. |
@@ -80,6 +80,13 b' def make_line_buffered(stream):' | |||||
80 | return LineBufferedWrapper(stream) |
|
80 | return LineBufferedWrapper(stream) | |
81 |
|
81 | |||
82 |
|
82 | |||
|
83 | def unwrap_line_buffered(stream): | |||
|
84 | if isinstance(stream, LineBufferedWrapper): | |||
|
85 | assert not isinstance(stream.orig, LineBufferedWrapper) | |||
|
86 | return stream.orig | |||
|
87 | return stream | |||
|
88 | ||||
|
89 | ||||
83 | class WriteAllWrapper(object): |
|
90 | class WriteAllWrapper(object): | |
84 | def __init__(self, orig): |
|
91 | def __init__(self, orig): | |
85 | self.orig = orig |
|
92 | self.orig = orig |
General Comments 0
You need to be logged in to leave comments.
Login now