]> git-server-git.apps.pok.os.sepia.ceph.com Git - remoto.git/commitdiff
be faithful about stderr and stdout remote output order
authorAlfredo Deza <alfredo@deza.pe>
Tue, 28 Oct 2014 14:26:07 +0000 (10:26 -0400)
committerAlfredo Deza <alfredo@deza.pe>
Tue, 28 Oct 2014 14:26:07 +0000 (10:26 -0400)
Fixes #8.

remoto/process.py

index 41446f747468188cc545fbd23cfa8fd8c2522300..f2445a55920127eb69e1eda44323bc53e1012fbc 100644 (file)
@@ -6,6 +6,7 @@ from .util import admin_command, RemoteError
 def _remote_run(channel, cmd, **kw):
     import subprocess
     import sys
+    from select import select
     stop_on_nonzero = kw.pop('stop_on_nonzero', True)
 
     process = subprocess.Popen(
@@ -16,28 +17,34 @@ def _remote_run(channel, cmd, **kw):
         **kw
     )
 
-    if process.stdout:
-        while True:
-            out = process.stdout.readline()
-            if out == '' and process.poll() is not None:
-                break
-            if out != '':
-                channel.send({'debug': out})
-                sys.stdout.flush()
-
-    if process.stderr:
-        while True:
-            err = process.stderr.readline()
-            if err == '' and process.poll() is not None:
-                break
-            if err != '':
-                channel.send({'warning': err})
-                sys.stderr.flush()
+    while True:
+        reads, _, _ = select(
+            [process.stdout.fileno(), process.stderr.fileno()],
+            [], []
+        )
+
+        for descriptor in reads:
+            if descriptor == process.stdout.fileno():
+                read = process.stdout.readline()
+                if read:
+                    channel.send({'debug': read})
+                    sys.stdout.flush()
+
+            if descriptor == process.stderr.fileno():
+                read = process.stderr.readline()
+                if read:
+                    channel.send({'warning': read})
+                    sys.stderr.flush()
+
+        if process.poll() is not None:
+            break
 
     returncode = process.wait()
     if returncode != 0:
         if stop_on_nonzero:
-            raise RuntimeError("command returned non-zero exit status: %s" % returncode)
+            raise RuntimeError(
+                "command returned non-zero exit status: %s" % returncode
+            )
         else:
             channel.send({'warning': "command returned non-zero exit status: %s" % returncode})