Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement