From 2e7029116204cf2d6f516e4514091f0b492bc689 Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Tue, 1 Nov 2016 11:23:38 -0700 Subject: 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 --- git_command.py | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) (limited to 'git_command.py') 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 @@ # limitations under the License. from __future__ import print_function -import fcntl import os -import select import sys import subprocess import tempfile from signal import SIGTERM + from error import GitError +import platform_utils from trace import REPO_TRACE, IsTrace, Trace from wrapper import Wrapper @@ -78,16 +78,6 @@ def terminate_ssh_clients(): _git_version = None -class _sfd(object): - """select file descriptor class""" - def __init__(self, fd, dest, std_name): - assert std_name in ('stdout', 'stderr') - self.fd = fd - self.dest = dest - self.std_name = std_name - def fileno(self): - return self.fd.fileno() - class _GitCall(object): def version(self): p = GitCommand(None, ['--version'], capture_stdout=True) @@ -253,19 +243,16 @@ class GitCommand(object): def _CaptureOutput(self): p = self.process - s_in = [_sfd(p.stdout, sys.stdout, 'stdout'), - _sfd(p.stderr, sys.stderr, 'stderr')] + s_in = platform_utils.FileDescriptorStreams.create() + s_in.add(p.stdout, sys.stdout, 'stdout') + s_in.add(p.stderr, sys.stderr, 'stderr') self.stdout = '' self.stderr = '' - for s in s_in: - flags = fcntl.fcntl(s.fd, fcntl.F_GETFL) - fcntl.fcntl(s.fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) - - while s_in: - in_ready, _, _ = select.select(s_in, [], []) + while not s_in.is_done: + in_ready = s_in.select() for s in in_ready: - buf = s.fd.read(4096) + buf = s.read() if not buf: s_in.remove(s) continue -- cgit v1.2.3-54-g00ecf