[PATCH] fix pager on centos5 (python 2.4 subprocess bug)

mbac at panix.com mbac at panix.com
Fri Jul 6 17:13:48 CDT 2012


# HG changeset patch
# User Michael Bacarella <mbacarella at janestreet.com>
# Date 1341612412 14400
# Node ID b88b743c1721e3957d6497c93c2e7151dc2261a4
# Parent  2e13c1bd34dc6afda8fc7cfa22a8cd658276724f
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.

diff --git a/hgext/pager.py b/hgext/pager.py
--- a/hgext/pager.py
+++ b/hgext/pager.py
@@ -53,7 +53,35 @@
 
 testedwith = 'internal'
 
-def _runpager(ui, p):
+def _runpager_compat(p):
+    if not util.safehasattr(os, 'fork'):
+        sys.stdout = util.popen(p, 'wb')
+        if util.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 util.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 _runpager_subprocess(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):
+        _runpager_subprocess(ui, p)
+    else:
+        _runpager_compat(p)
+
 def uisetup(ui):
     if '--debugger' in sys.argv or not ui.formatted():
         return



More information about the Mercurial-devel mailing list