mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
Support pager on Windows
Windows does not support pipe|fork, but we can simulate by creating the pager as a child process, redirecting stdout/in/err appropriately and then waiting for the child process to terminate after we are done executing the repo command. Change-Id: I5dd2bdeb4095e4d93bc678802e53c6d4eda0235b
This commit is contained in:
parent
227ad2ef42
commit
e8595e9df7
3
main.py
3
main.py
@ -55,7 +55,7 @@ from error import NoSuchProjectError
|
|||||||
from error import RepoChangedException
|
from error import RepoChangedException
|
||||||
import gitc_utils
|
import gitc_utils
|
||||||
from manifest_xml import GitcManifest, XmlManifest
|
from manifest_xml import GitcManifest, XmlManifest
|
||||||
from pager import RunPager
|
from pager import RunPager, TerminatePager
|
||||||
from wrapper import WrapperPath, Wrapper
|
from wrapper import WrapperPath, Wrapper
|
||||||
|
|
||||||
from subcmds import all_commands
|
from subcmds import all_commands
|
||||||
@ -542,6 +542,7 @@ def _Main(argv):
|
|||||||
print('fatal: %s' % e, file=sys.stderr)
|
print('fatal: %s' % e, file=sys.stderr)
|
||||||
result = 128
|
result = 128
|
||||||
|
|
||||||
|
TerminatePager()
|
||||||
sys.exit(result)
|
sys.exit(result)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
38
pager.py
38
pager.py
@ -16,19 +16,53 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
import select
|
import select
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import platform_utils
|
||||||
|
|
||||||
active = False
|
active = False
|
||||||
|
pager_process = None
|
||||||
|
old_stdout = None
|
||||||
|
old_stderr = None
|
||||||
|
|
||||||
def RunPager(globalConfig):
|
def RunPager(globalConfig):
|
||||||
global active
|
|
||||||
|
|
||||||
if not os.isatty(0) or not os.isatty(1):
|
if not os.isatty(0) or not os.isatty(1):
|
||||||
return
|
return
|
||||||
pager = _SelectPager(globalConfig)
|
pager = _SelectPager(globalConfig)
|
||||||
if pager == '' or pager == 'cat':
|
if pager == '' or pager == 'cat':
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if platform_utils.isWindows():
|
||||||
|
_PipePager(pager);
|
||||||
|
else:
|
||||||
|
_ForkPager(pager)
|
||||||
|
|
||||||
|
def TerminatePager():
|
||||||
|
global pager_process, old_stdout, old_stderr
|
||||||
|
if pager_process:
|
||||||
|
sys.stdout.flush()
|
||||||
|
sys.stderr.flush()
|
||||||
|
pager_process.stdin.close()
|
||||||
|
pager_process.wait();
|
||||||
|
pager_process = None
|
||||||
|
# Restore initial stdout/err in case there is more output in this process
|
||||||
|
# after shutting down the pager process
|
||||||
|
sys.stdout = old_stdout
|
||||||
|
sys.stderr = old_stderr
|
||||||
|
|
||||||
|
def _PipePager(pager):
|
||||||
|
global pager_process, old_stdout, old_stderr
|
||||||
|
assert pager_process is None, "Only one active pager process at a time"
|
||||||
|
# Create pager process, piping stdout/err into its stdin
|
||||||
|
pager_process = subprocess.Popen([pager], stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr)
|
||||||
|
old_stdout = sys.stdout
|
||||||
|
old_stderr = sys.stderr
|
||||||
|
sys.stdout = pager_process.stdin
|
||||||
|
sys.stderr = pager_process.stdin
|
||||||
|
|
||||||
|
def _ForkPager(pager):
|
||||||
|
global active
|
||||||
# This process turns into the pager; a child it forks will
|
# This process turns into the pager; a child it forks will
|
||||||
# do the real processing and output back to the pager. This
|
# do the real processing and output back to the pager. This
|
||||||
# is necessary to keep the pager in control of the tty.
|
# is necessary to keep the pager in control of the tty.
|
||||||
|
Loading…
Reference in New Issue
Block a user