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 |