Mercurial > hg > jslab
diff src/samer/silk/Terminal.java @ 0:bf79fb79ee13
Initial Mercurial check in.
author | samer |
---|---|
date | Tue, 17 Jan 2012 17:50:20 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/samer/silk/Terminal.java Tue Jan 17 17:50:20 2012 +0000 @@ -0,0 +1,106 @@ +package samer.silk; +import java.net.*; +import java.io.*; +import jsint.*; + +/** Terminal to acces a remote JVM. + Connects to a given port on the remote host, + then relays System.in and out to the socket. + */ + +public class Terminal { + + public static void connect(Socket sock) throws Exception { connect(sock,null); } + public static void connect(Socket sock, Procedure readline) throws Exception { + InputStream in=sock.getInputStream(); + OutputStream out=sock.getOutputStream(); + Thread reader=new Thread(new Transfer(in,System.out)); + + reader.start(); // everything coming from socket gets squirted to stdout + + // this end should be responsible for writing prompt + if (readline!=null) { + PrintWriter prn=new PrintWriter(out,true); + try { + for (;;) { + prn.println((String)SI.call(readline,"remote> ")); + Thread.sleep(100); // wait for reply + } + } catch (Exception ex) {} + } else (new Transfer(System.in,out)).run(); + System.out.println(); + + sock.shutdownOutput(); // other end should notice this + reader.join(5000); // wait for reader to die, 5 seconds max + sock.close(); + } + + + static class Transfer implements Runnable { + InputStream in; + OutputStream out; + byte [] buffer; + + public Transfer(InputStream in, OutputStream out) { + this.in=in; + this.out=out; + buffer=new byte[2048]; + } + + public void run() { + int n; + try { + do { + n=in.read(buffer,0,2048); + if (n>0) { out.write(buffer,0,n); out.flush(); } + } while (n>=0); + } catch (Exception ex) { ex.printStackTrace(); } + System.err.println("reader thread terminating."); + } + } + + public static void REPL(Socket call) throws Exception + { + Evaluator evaluator=Scheme.currentEvaluator(); + + PrintWriter oldout=evaluator.getOutput(); + PrintWriter olderr=evaluator.getError(); + PrintWriter newout=new PrintWriter(call.getOutputStream(),true); + InputPort newin=new InputPort(new BufferedReader( + new InputStreamReader(call.getInputStream()))); + + + oldout.println("... starting new remote REPL."); + newout.println("Welcome to remote JVM - Type Ctrl-D to terminate session."); + + // would like to replace System.err and System.out + // with multicast streams + evaluator.setOutput(newout); + evaluator.setError(newout); + + try { + evaluator.readEvalWriteLoop("remote> "); +/* Old version, can't work with jscheme 7.2 + Object x; + while (!Scheme.EXIT) { + try { + newout.print("remote> "); newout.flush(); + if ((x = newin.read()) == InputPort.EOF) break; + U.write(evaluator.eval(x), newout, true); + newout.println(); newout.flush(); + } catch (Throwable e) { e.printStackTrace(newout); newout.flush(); } + } +*/ + // try to let the other end know that the show's over + call.shutdownInput(); + } + finally { + newout.println("Remote session terminated."); + oldout.println("... remote REPL terminated."); + evaluator.setOutput(oldout); + evaluator.setError(olderr); + evaluator.setExit(false); // remote session not allowed to terminate JVM! + call.close(); // ?? or shutdownOutput(); + } + } +}