diff options
author | Renaud Paquay <rpaquay@google.com> | 2016-11-01 11:23:38 -0700 |
---|---|---|
committer | David Pursehouse <dpursehouse@collab.net> | 2017-05-29 19:29:30 +0900 |
commit | 2e7029116204cf2d6f516e4514091f0b492bc689 (patch) | |
tree | 0048544773ddc9d21706dfcc7307bdd3e2f6971f /git_command.py | |
parent | 35d22217a5ed2f8b5b9b183217923071ccfe7f37 (diff) | |
download | git-repo-2e7029116204cf2d6f516e4514091f0b492bc689.tar.gz |
Make "git command" and "forall" work on Windows
Python on Windows does not support non blocking file operations.
To workaround this issue, we instead use Threads and a Queue to
simulate non-blocking calls. This is happens only when running
with the native Windows version of Python, meaning Linux and Cygwin
are not affected by this change.
Change-Id: I4ce23827b096c5138f67a85c721f58a12279bb6f
Diffstat (limited to 'git_command.py')
-rw-r--r-- | git_command.py | 29 |
1 files changed, 8 insertions, 21 deletions
diff --git a/git_command.py b/git_command.py index 9f7d2930..dfa6a924 100644 --- a/git_command.py +++ b/git_command.py | |||
@@ -14,14 +14,14 @@ | |||
14 | # limitations under the License. | 14 | # limitations under the License. |
15 | 15 | ||
16 | from __future__ import print_function | 16 | from __future__ import print_function |
17 | import fcntl | ||
18 | import os | 17 | import os |
19 | import select | ||
20 | import sys | 18 | import sys |
21 | import subprocess | 19 | import subprocess |
22 | import tempfile | 20 | import tempfile |
23 | from signal import SIGTERM | 21 | from signal import SIGTERM |
22 | |||
24 | from error import GitError | 23 | from error import GitError |
24 | import platform_utils | ||
25 | from trace import REPO_TRACE, IsTrace, Trace | 25 | from trace import REPO_TRACE, IsTrace, Trace |
26 | from wrapper import Wrapper | 26 | from wrapper import Wrapper |
27 | 27 | ||
@@ -78,16 +78,6 @@ def terminate_ssh_clients(): | |||
78 | 78 | ||
79 | _git_version = None | 79 | _git_version = None |
80 | 80 | ||
81 | class _sfd(object): | ||
82 | """select file descriptor class""" | ||
83 | def __init__(self, fd, dest, std_name): | ||
84 | assert std_name in ('stdout', 'stderr') | ||
85 | self.fd = fd | ||
86 | self.dest = dest | ||
87 | self.std_name = std_name | ||
88 | def fileno(self): | ||
89 | return self.fd.fileno() | ||
90 | |||
91 | class _GitCall(object): | 81 | class _GitCall(object): |
92 | def version(self): | 82 | def version(self): |
93 | p = GitCommand(None, ['--version'], capture_stdout=True) | 83 | p = GitCommand(None, ['--version'], capture_stdout=True) |
@@ -253,19 +243,16 @@ class GitCommand(object): | |||
253 | 243 | ||
254 | def _CaptureOutput(self): | 244 | def _CaptureOutput(self): |
255 | p = self.process | 245 | p = self.process |
256 | s_in = [_sfd(p.stdout, sys.stdout, 'stdout'), | 246 | s_in = platform_utils.FileDescriptorStreams.create() |
257 | _sfd(p.stderr, sys.stderr, 'stderr')] | 247 | s_in.add(p.stdout, sys.stdout, 'stdout') |
248 | s_in.add(p.stderr, sys.stderr, 'stderr') | ||
258 | self.stdout = '' | 249 | self.stdout = '' |
259 | self.stderr = '' | 250 | self.stderr = '' |
260 | 251 | ||
261 | for s in s_in: | 252 | while not s_in.is_done: |
262 | flags = fcntl.fcntl(s.fd, fcntl.F_GETFL) | 253 | in_ready = s_in.select() |
263 | fcntl.fcntl(s.fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) | ||
264 | |||
265 | while s_in: | ||
266 | in_ready, _, _ = select.select(s_in, [], []) | ||
267 | for s in in_ready: | 254 | for s in in_ready: |
268 | buf = s.fd.read(4096) | 255 | buf = s.read() |
269 | if not buf: | 256 | if not buf: |
270 | s_in.remove(s) | 257 | s_in.remove(s) |
271 | continue | 258 | continue |