[SCM] morituri/master: * morituri/extern (added): * morituri/extern/__init__.py (added): * morituri/extern/asyncsub.py (added): Add extern module; add asynchronous subprocess Popen from http://code.activestate.com/recipes/440554/

js at users.alioth.debian.org js at users.alioth.debian.org
Sun Oct 19 20:08:47 UTC 2014


The following commit has been merged in the master branch:
commit 0fe1be06b73bd016fc16ed685883047d3cff71d5
Author: Thomas Vander Stichele <thomas (at) apestaart (dot) org>
Date:   Sun Apr 19 17:26:05 2009 +0000

    	* morituri/extern (added):
    	* morituri/extern/__init__.py (added):
    	* morituri/extern/asyncsub.py (added):
    	  Add extern module; add asynchronous subprocess Popen from
    	  http://code.activestate.com/recipes/440554/

diff --git a/ChangeLog b/ChangeLog
index c12f24f..5903081 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-04-19  Thomas Vander Stichele  <thomas at apestaart dot org>
+
+	* morituri/extern (added):
+	* morituri/extern/__init__.py (added):
+	* morituri/extern/asyncsub.py (added):
+	  Add extern module; add asynchronous subprocess Popen from
+	  http://code.activestate.com/recipes/440554/
+
 2009-04-15  Thomas Vander Stichele  <thomas at apestaart dot org>
 
 	* examples/gtkchecksum.py:
diff --git a/morituri/__init__.py b/morituri/extern/__init__.py
similarity index 100%
copy from morituri/__init__.py
copy to morituri/extern/__init__.py
diff --git a/morituri/extern/asyncsub.py b/morituri/extern/asyncsub.py
new file mode 100644
index 0000000..219faf3
--- /dev/null
+++ b/morituri/extern/asyncsub.py
@@ -0,0 +1,168 @@
+# -*- Mode: Python -*-
+# vi:si:et:sw=4:sts=4:ts=4
+
+# from http://code.activestate.com/recipes/440554/
+
+import os
+import subprocess
+import errno
+import time
+import sys
+
+PIPE = subprocess.PIPE
+
+if subprocess.mswindows:
+    from win32file import ReadFile, WriteFile
+    from win32pipe import PeekNamedPipe
+    import msvcrt
+else:
+    import select
+    import fcntl
+
+class Popen(subprocess.Popen):
+    def recv(self, maxsize=None):
+        return self._recv('stdout', maxsize)
+    
+    def recv_err(self, maxsize=None):
+        return self._recv('stderr', maxsize)
+
+    def send_recv(self, input='', maxsize=None):
+        return self.send(input), self.recv(maxsize), self.recv_err(maxsize)
+
+    def get_conn_maxsize(self, which, maxsize):
+        if maxsize is None:
+            maxsize = 1024
+        elif maxsize < 1:
+            maxsize = 1
+        return getattr(self, which), maxsize
+    
+    def _close(self, which):
+        getattr(self, which).close()
+        setattr(self, which, None)
+    
+    if subprocess.mswindows:
+        def send(self, input):
+            if not self.stdin:
+                return None
+
+            try:
+                x = msvcrt.get_osfhandle(self.stdin.fileno())
+                (errCode, written) = WriteFile(x, input)
+            except ValueError:
+                return self._close('stdin')
+            except (subprocess.pywintypes.error, Exception), why:
+                if why[0] in (109, errno.ESHUTDOWN):
+                    return self._close('stdin')
+                raise
+
+            return written
+
+        def _recv(self, which, maxsize):
+            conn, maxsize = self.get_conn_maxsize(which, maxsize)
+            if conn is None:
+                return None
+            
+            try:
+                x = msvcrt.get_osfhandle(conn.fileno())
+                (read, nAvail, nMessage) = PeekNamedPipe(x, 0)
+                if maxsize < nAvail:
+                    nAvail = maxsize
+                if nAvail > 0:
+                    (errCode, read) = ReadFile(x, nAvail, None)
+            except ValueError:
+                return self._close(which)
+            except (subprocess.pywintypes.error, Exception), why:
+                if why[0] in (109, errno.ESHUTDOWN):
+                    return self._close(which)
+                raise
+            
+            if self.universal_newlines:
+                read = self._translate_newlines(read)
+            return read
+
+    else:
+        def send(self, input):
+            if not self.stdin:
+                return None
+
+            if not select.select([], [self.stdin], [], 0)[1]:
+                return 0
+
+            try:
+                written = os.write(self.stdin.fileno(), input)
+            except OSError, why:
+                if why[0] == errno.EPIPE: #broken pipe
+                    return self._close('stdin')
+                raise
+
+            return written
+
+        def _recv(self, which, maxsize):
+            conn, maxsize = self.get_conn_maxsize(which, maxsize)
+            if conn is None:
+                return None
+            
+            flags = fcntl.fcntl(conn, fcntl.F_GETFL)
+            if not conn.closed:
+                fcntl.fcntl(conn, fcntl.F_SETFL, flags| os.O_NONBLOCK)
+            
+            try:
+                if not select.select([conn], [], [], 0)[0]:
+                    return ''
+                
+                r = conn.read(maxsize)
+                if not r:
+                    return self._close(which)
+    
+                if self.universal_newlines:
+                    r = self._translate_newlines(r)
+                return r
+            finally:
+                if not conn.closed:
+                    fcntl.fcntl(conn, fcntl.F_SETFL, flags)
+
+message = "Other end disconnected!"
+
+def recv_some(p, t=.1, e=1, tr=5, stderr=0):
+    if tr < 1:
+        tr = 1
+    x = time.time()+t
+    y = []
+    r = ''
+    pr = p.recv
+    if stderr:
+        pr = p.recv_err
+    while time.time() < x or r:
+        r = pr()
+        if r is None:
+            if e:
+                raise Exception(message)
+            else:
+                break
+        elif r:
+            y.append(r)
+        else:
+            time.sleep(max((x-time.time())/tr, 0))
+    return ''.join(y)
+    
+def send_all(p, data):
+    while len(data):
+        sent = p.send(data)
+        if sent is None:
+            raise Exception(message)
+        data = buffer(data, sent)
+
+if __name__ == '__main__':
+    if sys.platform == 'win32':
+        shell, commands, tail = ('cmd', ('dir /w', 'echo HELLO WORLD'), '\r\n')
+    else:
+        shell, commands, tail = ('sh', ('ls', 'echo HELLO WORLD'), '\n')
+    
+    a = Popen(shell, stdin=PIPE, stdout=PIPE)
+    print recv_some(a),
+    for cmd in commands:
+        send_all(a, cmd + tail)
+        print recv_some(a),
+    send_all(a, 'exit' + tail)
+    print recv_some(a, e=0)
+    a.wait()

-- 
morituri packaging



More information about the pkg-multimedia-commits mailing list