try:
import fcntl
except:
fcntl = None
import os
import sys
from subprocess import Popen,PIPE
import socket
from StringIO import StringIO
from netrepr import NetRepr,RemoteObjectPool,RemoteObjectReference
IMPORT_MODULES = ['netrepr', 'remote_console', 'remote_pipe', 'remote_bootstrap']
source = StringIO()
for fn in IMPORT_MODULES:
for line in file(fn+'.py', 'rU'):
source.write(line)
source.write('\n\n')
SOURCE = repr(source.getvalue()) + '\n'
def ensure_utf8(s):
if isinstance(s, unicode):
s = s.encode('utf-8')
return s
def bind_and_listen(hostport):
if isinstance(hostport, str):
host, port = hostport.split(':')
hostport = (host, int(port))
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# set close-on-exec
if hasattr(fcntl, 'FD_CLOEXEC'):
old = fcntl.fcntl(serversock.fileno(), fcntl.F_GETFD)
fcntl.fcntl(serversock.fileno(), fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
# allow the address to be re-used in a reasonable amount of time
if os.name == 'posix' and sys.platform != 'cygwin':
serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversock.bind(hostport)
serversock.listen(5)
return serversock
def open_connection(executable=sys.executable):
serversock = bind_and_listen(('127.0.0.1', 0))
hostport = serversock.getsockname()
proc = Popen([executable, 'tcpinterpreter.py', repr(hostport)], stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
clientsock, address = serversock.accept()
serversock.shutdown(2)
return clientsock, proc
def start_client(clientsock):
f = clientsock.makefile('r+b', 0)
f.write(SOURCE)
f.flush()
return f
def client_loop(f):
def writecode(code):
#print '[code: %r]' % (code,)
f.write(repr(code) + '\n')
pool = RemoteObjectPool(writecode)
netRepr = NetRepr(pool)
netrepr = netRepr.netrepr
def neteval(s):
return eval(s, pool.namespace, pool.namespace)
while True:
code = f.readline().rstrip()
pool.push()
try:
if not code:
break
command = eval(code)
basic = eval(command[0])
if basic == 'expect':
seq = eval(command[1])
name = eval(command[2])
args = map(neteval, command[3:])
code = None
rval = None
if name == 'RemoteConsole.raw_input':
try:
rval = raw_input(*args)
except EOFError:
code = 'raise EOFError'
elif name == 'RemoteConsole.write':
sys.stdout.write(ensure_utf8(args[0]))
elif name == 'RemoteConsole.displayhook':
pass
obj = args[0]
if obj is None:
pass
elif isinstance(obj, RemoteObjectReference):
writecode('interp.write(repr(%s) + "\\n")' % (netrepr(obj),))
else:
print repr(obj)
elif name.startswith('RemoteFileLike.'):
fh = getattr(sys, args[0])
meth = getattr(fh, name[len('RemoteFileLike.'):])
rval = meth(*map(ensure_utf8, args[1:]))
else:
print name, args
if code is None:
code = '__result__[%r] = %r' % (seq, rval)
writecode(code)
finally:
pool.pop()
def main():
clientsock, proc = open_connection()
f = start_client(clientsock)
try:
client_loop(f)
finally:
f.close()
clientsock.close()
proc.stdin.close()
print '[stdout]', proc.stdout.read()
print '[stderr]', proc.stderr.read()
if __name__ == '__main__':
main()
|