changeset 17250:18f935b4c05a stable

pager: work around bug in python 2.4's subprocess module (issue3533) hg v2.2.2 fixed the pager on Windows, but broke it on Python 2.4. This patch only uses the new behavior if Python >= 2.5 is detected.
author Michael Bacarella <mbacarella@janestreet.com>
date Fri, 06 Jul 2012 18:06:52 -0400
parents 7d4747c711a9
children 98166640b356
files hgext/pager.py
diffstat 1 files changed, 38 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/pager.py	Wed Jul 25 19:02:35 2012 +0200
+++ b/hgext/pager.py	Fri Jul 06 18:06:52 2012 -0400
@@ -53,7 +53,35 @@
 
 testedwith = 'internal'
 
-def _runpager(ui, p):
+def _pagerfork(ui, p):
+    if not util.safehasattr(os, 'fork'):
+        sys.stdout = util.popen(p, 'wb')
+        if ui._isatty(sys.stderr):
+            sys.stderr = sys.stdout
+        return
+    fdin, fdout = os.pipe()
+    pid = os.fork()
+    if pid == 0:
+        os.close(fdin)
+        os.dup2(fdout, sys.stdout.fileno())
+        if ui._isatty(sys.stderr):
+            os.dup2(fdout, sys.stderr.fileno())
+        os.close(fdout)
+        return
+    os.dup2(fdin, sys.stdin.fileno())
+    os.close(fdin)
+    os.close(fdout)
+    try:
+        os.execvp('/bin/sh', ['/bin/sh', '-c', p])
+    except OSError, e:
+        if e.errno == errno.ENOENT:
+            # no /bin/sh, try executing the pager directly
+            args = shlex.split(p)
+            os.execvp(args[0], args)
+        else:
+            raise
+
+def _pagersubprocess(ui, p):
     pager = subprocess.Popen(p, shell=True, bufsize=-1,
                              close_fds=util.closefds, stdin=subprocess.PIPE,
                              stdout=sys.stdout, stderr=sys.stderr)
@@ -71,6 +99,15 @@
         os.dup2(stderr, sys.stderr.fileno())
         pager.wait()
 
+def _runpager(ui, p):
+    # The subprocess module shipped with Python <= 2.4 is buggy (issue3533).
+    # The compat version is buggy on Windows (issue3225), but has been shipping
+    # with hg for a long time.  Preserve existing functionality.
+    if sys.version_info >= (2, 5):
+        _pagersubprocess(ui, p)
+    else:
+        _pagerfork(ui, p)
+
 def uisetup(ui):
     if '--debugger' in sys.argv or not ui.formatted():
         return