Patchwork [1,of,3] platform: implement readpipe()

login
register
mail settings
Submitter Gregory Szorc
Date Aug. 16, 2014, 5:37 p.m.
Message ID <90f91db78e94294e5940.1408210640@vm-ubuntu-main.gateway.sonic.net>
Download mbox | patch
Permalink /patch/5453/
State Accepted
Headers show

Comments

Gregory Szorc - Aug. 16, 2014, 5:37 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1408158138 25200
#      Fri Aug 15 20:02:18 2014 -0700
# Node ID 90f91db78e94294e5940d0191f331323b97b3a96
# Parent  8dda6f6ff564d8fe6ac7b8ce4c74eb9bfb5de14a
platform: implement readpipe()

Reading all available data from a pipe has a platform-dependent
implementation.

This patch establishes platform.readpipe() by copying the
inline implementation in sshpeer.readerr(). The implementations
for POSIX and Windows are currently identical. The POSIX
implementation will be changed in a subsequent patch.

Patch

diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -566,4 +566,17 @@  def statislink(st):
 
 def statisexec(st):
     '''check whether a stat result is an executable file'''
     return st and (st.st_mode & 0100 != 0)
+
+def readpipe(pipe):
+    """Read all available data from a pipe."""
+    chunks = []
+    while True:
+        size = os.fstat(pipe.fileno()).st_size
+        if not size:
+            break
+
+        s = pipe.read(size)
+        if not s:
+            break
+        chunks.append(s)
diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py
--- a/mercurial/sshpeer.py
+++ b/mercurial/sshpeer.py
@@ -102,15 +102,10 @@  class sshpeer(wireproto.wirepeer):
     def _capabilities(self):
         return self._caps
 
     def readerr(self):
-        while True:
-            size = util.fstat(self.pipee).st_size
-            if size == 0:
-                break
-            s = self.pipee.read(size)
-            if not s:
-                break
+        s = util.readpipe(self.pipee)
+        if s:
             for l in s.splitlines():
                 self.ui.status(_("remote: "), l, '\n')
 
     def _abort(self, exception):
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -52,8 +52,9 @@  parsepatchoutput = platform.parsepatchou
 pconvert = platform.pconvert
 popen = platform.popen
 posixfile = platform.posixfile
 quotecommand = platform.quotecommand
+readpipe = platform.readpipe
 rename = platform.rename
 samedevice = platform.samedevice
 samefile = platform.samefile
 samestat = platform.samestat
diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -335,4 +335,19 @@  def statislink(st):
 
 def statisexec(st):
     '''check whether a stat result is an executable file'''
     return False
+
+def readpipe(pipe):
+    """Read all available data from a pipe."""
+    chunks = []
+    while True:
+        size = os.fstat(pipe.fileno()).st_size
+        if not size:
+            break
+
+        s = pipe.read(size)
+        if not s:
+            break
+        chunks.append(s)
+
+    return ''.join(chunks)