diff options
author | Renaud Paquay <rpaquay@google.com> | 2016-11-01 15:51:59 -0700 |
---|---|---|
committer | Renaud Paquay <rpaquay@google.com> | 2017-08-31 13:49:26 -0700 |
commit | e8595e9df7980b0b7d9111de43d294c4439d474c (patch) | |
tree | 1a7034b7854eb47965b8112ccaf3b33687cac583 | |
parent | 227ad2ef42f47798d24814dfc2cef8119c313ab7 (diff) | |
download | git-repo-e8595e9df7980b0b7d9111de43d294c4439d474c.tar.gz |
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
-rwxr-xr-x | main.py | 3 | ||||
-rwxr-xr-x | pager.py | 38 |
2 files changed, 38 insertions, 3 deletions
@@ -55,7 +55,7 @@ from error import NoSuchProjectError | |||
55 | from error import RepoChangedException | 55 | from error import RepoChangedException |
56 | import gitc_utils | 56 | import gitc_utils |
57 | from manifest_xml import GitcManifest, XmlManifest | 57 | from manifest_xml import GitcManifest, XmlManifest |
58 | from pager import RunPager | 58 | from pager import RunPager, TerminatePager |
59 | from wrapper import WrapperPath, Wrapper | 59 | from wrapper import WrapperPath, Wrapper |
60 | 60 | ||
61 | from subcmds import all_commands | 61 | from subcmds import all_commands |
@@ -542,6 +542,7 @@ def _Main(argv): | |||
542 | print('fatal: %s' % e, file=sys.stderr) | 542 | print('fatal: %s' % e, file=sys.stderr) |
543 | result = 128 | 543 | result = 128 |
544 | 544 | ||
545 | TerminatePager() | ||
545 | sys.exit(result) | 546 | sys.exit(result) |
546 | 547 | ||
547 | if __name__ == '__main__': | 548 | if __name__ == '__main__': |
@@ -16,19 +16,53 @@ | |||
16 | from __future__ import print_function | 16 | from __future__ import print_function |
17 | import os | 17 | import os |
18 | import select | 18 | import select |
19 | import subprocess | ||
19 | import sys | 20 | import sys |
20 | 21 | ||
22 | import platform_utils | ||
23 | |||
21 | active = False | 24 | active = False |
25 | pager_process = None | ||
26 | old_stdout = None | ||
27 | old_stderr = None | ||
22 | 28 | ||
23 | def RunPager(globalConfig): | 29 | def RunPager(globalConfig): |
24 | global active | ||
25 | |||
26 | if not os.isatty(0) or not os.isatty(1): | 30 | if not os.isatty(0) or not os.isatty(1): |
27 | return | 31 | return |
28 | pager = _SelectPager(globalConfig) | 32 | pager = _SelectPager(globalConfig) |
29 | if pager == '' or pager == 'cat': | 33 | if pager == '' or pager == 'cat': |
30 | return | 34 | return |
31 | 35 | ||
36 | if platform_utils.isWindows(): | ||
37 | _PipePager(pager); | ||
38 | else: | ||
39 | _ForkPager(pager) | ||
40 | |||
41 | def TerminatePager(): | ||
42 | global pager_process, old_stdout, old_stderr | ||
43 | if pager_process: | ||
44 | sys.stdout.flush() | ||
45 | sys.stderr.flush() | ||
46 | pager_process.stdin.close() | ||
47 | pager_process.wait(); | ||
48 | pager_process = None | ||
49 | # Restore initial stdout/err in case there is more output in this process | ||
50 | # after shutting down the pager process | ||
51 | sys.stdout = old_stdout | ||
52 | sys.stderr = old_stderr | ||
53 | |||
54 | def _PipePager(pager): | ||
55 | global pager_process, old_stdout, old_stderr | ||
56 | assert pager_process is None, "Only one active pager process at a time" | ||
57 | # Create pager process, piping stdout/err into its stdin | ||
58 | pager_process = subprocess.Popen([pager], stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr) | ||
59 | old_stdout = sys.stdout | ||
60 | old_stderr = sys.stderr | ||
61 | sys.stdout = pager_process.stdin | ||
62 | sys.stderr = pager_process.stdin | ||
63 | |||
64 | def _ForkPager(pager): | ||
65 | global active | ||
32 | # This process turns into the pager; a child it forks will | 66 | # This process turns into the pager; a child it forks will |
33 | # do the real processing and output back to the pager. This | 67 | # do the real processing and output back to the pager. This |
34 | # is necessary to keep the pager in control of the tty. | 68 | # is necessary to keep the pager in control of the tty. |