summaryrefslogtreecommitdiffstats
path: root/git_command.py
diff options
context:
space:
mode:
authorRenaud Paquay <rpaquay@google.com>2016-11-01 11:23:38 -0700
committerDavid Pursehouse <dpursehouse@collab.net>2017-05-29 19:29:30 +0900
commit2e7029116204cf2d6f516e4514091f0b492bc689 (patch)
tree0048544773ddc9d21706dfcc7307bdd3e2f6971f /git_command.py
parent35d22217a5ed2f8b5b9b183217923071ccfe7f37 (diff)
downloadgit-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.py29
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
16from __future__ import print_function 16from __future__ import print_function
17import fcntl
18import os 17import os
19import select
20import sys 18import sys
21import subprocess 19import subprocess
22import tempfile 20import tempfile
23from signal import SIGTERM 21from signal import SIGTERM
22
24from error import GitError 23from error import GitError
24import platform_utils
25from trace import REPO_TRACE, IsTrace, Trace 25from trace import REPO_TRACE, IsTrace, Trace
26from wrapper import Wrapper 26from 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
81class _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
91class _GitCall(object): 81class _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