#!/usr/bin/env python import sys import select import socket import empty import thr import cmd_ut import dbg def fs_default_new(): g_b1 = lambda f: f.read( 1 ) def g_b( f ): fs = get_fs( f ) b = b'' while not b or fs.c_g( f ): b1 = fs.g_b1( f ) if not b1: break b += b1 return b c_g = lambda f, tmout=0: select.select( [ f ], [], [], tmout )[ 0 ] == [ f ] p_b = lambda f, b: f.write( b ) return empty.new( locals() ) fs_df = fs_default_new() def b1_th_new( f, g_b1_ ): q = thr.que_new() def th_f(): b1 = g_b1_( f ) q.put( b1 ) th = thr.loop_new( th_f ) thr.ths.start( th ) def stop(): th.stop() def g_b1( f ): return q.get() g_b = fs_df.g_b def c_g( f ): return not q.is_empty() return empty.new( locals() ) fdic = {} def set_fs( fi, fo, g_b1=fs_df.g_b1, g_b=fs_df.g_b, c_g=fs_df.c_g, new_b1_th=False, p_b=fs_df.p_b ): b1_th=None if new_b1_th: b1_th = b1_th_new( fi, g_b1 ) g_b1 = b1_th.g_b1 g_b = b1_th.g_b c_g = b1_th.c_g if fi == fo: fdic[ fi ] = empty.new( g_b1=g_b1, g_b=g_b, c_g=c_g, b1_th=b1_th, p_b=p_b ) else: fdic[ fi ] = empty.new( g_b1=g_b1, g_b=g_b, c_g=c_g, b1_th=b1_th, p_b=None ) fdic[ fo ] = empty.new( g_b1=None, g_b=None, c_b=None, b1_th=None, p_b=p_b ) def set_fs_sock( f ): g_b1 = lambda f: f.recv( 1 ) g_b = lambda f: f.recv( 1024 * 16 ) p_b = lambda f, b: f.sendall( b ) set_fs( f, f, g_b1=g_b1, g_b=g_b, p_b=p_b ) def set_fs_sys_stdio(): get_buffer = lambda f: f.buffer if hasattr( f, 'buffer' ) else f fi = get_buffer( sys.stdin ) fo = get_buffer( sys.stdout ) set_fs( fi, fo ) return ( fi, fo ) def set_fs_proc_stdio( proc ): fi = proc.stdout fo = proc.stdin set_fs( fi, fo, new_b1_th=True ) return ( fi, fo ) def get_fs( f ): if f not in fdic: set_fs( f, f ) return fdic.get( f ) def del_fs( f ): if f not in fdic: return fs = get_fs( f ) if fs.b1_th: # need kill proc of f, for return blocked get_b1 fs.b1_th.stop() fdic.pop( f ) def close( f ): del_fs( f ) f.close() def g_b1( f ): fs = get_fs( f ) b = b'' if not fs.g_b1: return b b1 = fs.g_b1( f ) if b1: b = b1 return b def g_b( f ): fs = get_fs( f ) b = b'' if not fs.g_b: return b b = fs.g_b( f ) return b def g_b_line( f ): fs = get_fs( f ) b = b'' if not fs.g_b1: return b while True: b1 = fs.g_b1( f ) if not b1: break b += b1 if b1 == b'\n': break return b def g_b_all( f ): fs = get_fs( f ) b = b'' if not fs.g_b or not fs.c_g: return b while not b or fs.c_g( f ): b_ = fs.g_b( f ) if not b_: break b += b_ return b def c_g( f ): fs = get_fs( f ) if not fs.c_g: return False return fs.c_g( f ) def p_b( f, b ): fs = get_fs( f ) if not fs.p_b: return False try: fs.p_b( f, b ) except: return False if hasattr( f, 'flush' ): f.flush() return True to_s = lambda bt: bt.decode( 'utf-8' ) to_b = lambda s: s.encode( 'utf-8' ) g_s1 = lambda f : to_s( g_b1( f ) ) g_s = lambda f: to_s( g_b( f ) ) g_s_line = lambda f: to_s( g_b_line( f ) ) g_s_all = lambda f: to_s( g_b_all( f ) ) p_s = lambda f, s: p_b( f, to_b( s ) ) def proc_new( cmd ): proc = cmd_ut.proc_new( cmd, stdin=cmd_ut.PIPE, stdout=cmd_ut.PIPE ) ( fi, fo ) = set_fs_proc_stdio( proc.proc ) def stop(): proc.kill() proc.wait() del_fs( fi ) del_fs( fo ) return empty.new( locals() ) def run(): ( fi, fo ) = set_fs_sys_stdio() cmd = 'cat' if len( sys.argv ) >= 2: cmd = ' '.join( sys.argv[ 1 : ] ) proc = proc_new( cmd ) port = 13579 host = 'localhost' e = empty.new() e.cs = None def srv(): ss = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) ss.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) ss.bind( ( '', port ) ) ss.listen( 5 ) ( e.cs, adr ) = ss.accept() th = thr.th_new( srv ) thr.ths.start( th ) sc = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) sc.connect( ( host, port ) ) set_fs_sock( sc ) th.stop() set_fs_sock( e.cs ) while True: b = g_b_line( fi ) if not b: break if not p_b( proc.fo, b ): break b = g_b_all( proc.fi ) if not b: break if not p_b( sc, b ): break b = g_b_all( e.cs ) if not b: break if not p_b( e.cs, b ): break b = g_b_all( sc ) if not b: break if not p_b( fo, b ): break close( sc ) close( e.cs ) proc.stop() del_fs( fi ) del_fs( fo ) if __name__ == "__main__": run() # EOF