Ver código fonte

define class StdoutTee

Fabian Peter Hammerle 6 anos atrás
pai
commit
9370fafa55
1 arquivos alterados com 31 adições e 0 exclusões
  1. 31 0
      rc.xsh

+ 31 - 0
rc.xsh

@@ -35,6 +35,7 @@ import select
 import shutil
 import subprocess
 import sys
+import threading
 
 # default locale
 # will be used for all non-explicitly set LC_* variables
@@ -76,6 +77,36 @@ $TERMCMD = os.path.join(os.path.dirname(__file__), 'ranger-termite-termcmd')
 # https://docs.docker.com/engine/security/trust/content_trust/
 $DOCKER_CONTENT_TRUST = 1
 
+class StdoutTee:
+
+    def __init__(self, sink):
+        self._sink = sink
+
+    def __enter__(self):
+        self._read_fd, self._write_fd = os.pipe()
+        self._thread = threading.Thread(target=self._loop)
+        self._thread.start()
+        return self
+
+    def _loop(self):
+        while True:
+            try:
+                data = os_read_non_blocking(self._read_fd)
+            except OSError:  # fd closed
+                return
+            if data:
+                self._sink.write(data)
+                sys.stdout.buffer.write(data)
+                sys.stdout.flush()
+
+    def fileno(self):
+        return self._write_fd
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        os.close(self._read_fd)
+        os.close(self._write_fd)
+        self._thread.join()
+
 def dpkg_listfiles(pkg_name):
     assert isinstance(pkg_name, str)
     paths = $(dpkg --listfiles @(pkg_name)).split('\n')[:-1]