hgext/pager.py
changeset 25201 59d794154e8d
parent 25186 80c5b2666a96
child 26452 499d5c98e98b
equal deleted inserted replaced
25200:3613819fb05f 25201:59d794154e8d
    53 used. Use a boolean value like yes, no, on, off, or use auto for
    53 used. Use a boolean value like yes, no, on, off, or use auto for
    54 normal behavior.
    54 normal behavior.
    55 
    55 
    56 '''
    56 '''
    57 
    57 
    58 import atexit, sys, os, signal, subprocess, errno, shlex
    58 import atexit, sys, os, signal, subprocess
    59 from mercurial import commands, dispatch, util, extensions, cmdutil
    59 from mercurial import commands, dispatch, util, extensions, cmdutil
    60 from mercurial.i18n import _
    60 from mercurial.i18n import _
    61 
    61 
    62 # Note for extension authors: ONLY specify testedwith = 'internal' for
    62 # Note for extension authors: ONLY specify testedwith = 'internal' for
    63 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
    63 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
    64 # be specifying the version(s) of Mercurial they are tested with, or
    64 # be specifying the version(s) of Mercurial they are tested with, or
    65 # leave the attribute unspecified.
    65 # leave the attribute unspecified.
    66 testedwith = 'internal'
    66 testedwith = 'internal'
    67 
       
    68 def _pagerfork(ui, p):
       
    69     if not util.safehasattr(os, 'fork'):
       
    70         sys.stdout = util.popen(p, 'wb')
       
    71         if ui._isatty(sys.stderr):
       
    72             sys.stderr = sys.stdout
       
    73         return
       
    74     fdin, fdout = os.pipe()
       
    75     pid = os.fork()
       
    76     if pid == 0:
       
    77         os.close(fdin)
       
    78         os.dup2(fdout, sys.stdout.fileno())
       
    79         if ui._isatty(sys.stderr):
       
    80             os.dup2(fdout, sys.stderr.fileno())
       
    81         os.close(fdout)
       
    82         return
       
    83     os.dup2(fdin, sys.stdin.fileno())
       
    84     os.close(fdin)
       
    85     os.close(fdout)
       
    86     try:
       
    87         os.execvp('/bin/sh', ['/bin/sh', '-c', p])
       
    88     except OSError, e:
       
    89         if e.errno == errno.ENOENT:
       
    90             # no /bin/sh, try executing the pager directly
       
    91             args = shlex.split(p)
       
    92             os.execvp(args[0], args)
       
    93         else:
       
    94             raise
       
    95 
    67 
    96 def _pagersubprocess(ui, p):
    68 def _pagersubprocess(ui, p):
    97     pager = subprocess.Popen(p, shell=True, bufsize=-1,
    69     pager = subprocess.Popen(p, shell=True, bufsize=-1,
    98                              close_fds=util.closefds, stdin=subprocess.PIPE,
    70                              close_fds=util.closefds, stdin=subprocess.PIPE,
    99                              stdout=sys.stdout, stderr=sys.stderr)
    71                              stdout=sys.stdout, stderr=sys.stderr)
   112         os.dup2(stdout, sys.stdout.fileno())
    84         os.dup2(stdout, sys.stdout.fileno())
   113         os.dup2(stderr, sys.stderr.fileno())
    85         os.dup2(stderr, sys.stderr.fileno())
   114         pager.wait()
    86         pager.wait()
   115 
    87 
   116 def _runpager(ui, p):
    88 def _runpager(ui, p):
   117     # The subprocess module shipped with Python <= 2.4 is buggy (issue3533).
    89     _pagersubprocess(ui, p)
   118     # The compat version is buggy on Windows (issue3225), but has been shipping
       
   119     # with hg for a long time.  Preserve existing functionality.
       
   120     if sys.version_info >= (2, 5):
       
   121         _pagersubprocess(ui, p)
       
   122     else:
       
   123         _pagerfork(ui, p)
       
   124 
    90 
   125 def uisetup(ui):
    91 def uisetup(ui):
   126     if '--debugger' in sys.argv or not ui.formatted():
    92     if '--debugger' in sys.argv or not ui.formatted():
   127         return
    93         return
   128 
    94