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();
+		}
+  	}
+}