view src/samer/silk/Terminal.java @ 8:5e3cbbf173aa tip

Reorganise some more
author samer
date Fri, 05 Apr 2019 22:41:58 +0100
parents bf79fb79ee13
children
line wrap: on
line source
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();
		}
  	}
}