diff mercurial/util.py @ 30876:3a4c0905f357

util: always force line buffered stdout when stdout is a tty (BC) pager replaced stdout with a line buffered version to work around glibc deciding on a buffering strategy on the first write to stdout. This is going to make my next patch hard, as replacing stdout will make tracking time spent blocked on it more challenging. Move the line buffering requirement to util.py, and remove it from pager. This means that the abuse of ui.formatted=True and pager set to cat or equivalent no longer results in a line-buffered output to a pipe, hence (BC), although I don't expect anyone to be affected
author Simon Farnsworth <simonfar@fb.com>
date Fri, 03 Feb 2017 15:10:27 -0800
parents 0126e422450e
children 82f1ef8b4477
line wrap: on
line diff
--- a/mercurial/util.py	Thu Feb 02 02:56:38 2017 -0800
+++ b/mercurial/util.py	Fri Feb 03 15:10:27 2017 -0800
@@ -63,9 +63,21 @@
 urlreq = pycompat.urlreq
 xmlrpclib = pycompat.xmlrpclib
 
+def isatty(fp):
+    try:
+        return fp.isatty()
+    except AttributeError:
+        return False
+
+# glibc determines buffering on first write to stdout - if we replace a TTY
+# destined stdout with a pipe destined stdout (e.g. pager), we want line
+# buffering
+if isatty(stdout):
+    stdout = os.fdopen(stdout.fileno(), 'wb', 1)
+
 if pycompat.osname == 'nt':
     from . import windows as platform
-    stdout = platform.winstdout(pycompat.stdout)
+    stdout = platform.winstdout(stdout)
 else:
     from . import posix as platform
 
@@ -2750,12 +2762,6 @@
     u.user = u.passwd = None
     return str(u)
 
-def isatty(fp):
-    try:
-        return fp.isatty()
-    except AttributeError:
-        return False
-
 timecount = unitcountfn(
     (1, 1e3, _('%.0f s')),
     (100, 1, _('%.1f s')),