annotate 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
rev   line source
samer@0 1 package samer.silk;
samer@0 2 import java.net.*;
samer@0 3 import java.io.*;
samer@0 4 import jsint.*;
samer@0 5
samer@0 6 /** Terminal to acces a remote JVM.
samer@0 7 Connects to a given port on the remote host,
samer@0 8 then relays System.in and out to the socket.
samer@0 9 */
samer@0 10
samer@0 11 public class Terminal {
samer@0 12
samer@0 13 public static void connect(Socket sock) throws Exception { connect(sock,null); }
samer@0 14 public static void connect(Socket sock, Procedure readline) throws Exception {
samer@0 15 InputStream in=sock.getInputStream();
samer@0 16 OutputStream out=sock.getOutputStream();
samer@0 17 Thread reader=new Thread(new Transfer(in,System.out));
samer@0 18
samer@0 19 reader.start(); // everything coming from socket gets squirted to stdout
samer@0 20
samer@0 21 // this end should be responsible for writing prompt
samer@0 22 if (readline!=null) {
samer@0 23 PrintWriter prn=new PrintWriter(out,true);
samer@0 24 try {
samer@0 25 for (;;) {
samer@0 26 prn.println((String)SI.call(readline,"remote> "));
samer@0 27 Thread.sleep(100); // wait for reply
samer@0 28 }
samer@0 29 } catch (Exception ex) {}
samer@0 30 } else (new Transfer(System.in,out)).run();
samer@0 31 System.out.println();
samer@0 32
samer@0 33 sock.shutdownOutput(); // other end should notice this
samer@0 34 reader.join(5000); // wait for reader to die, 5 seconds max
samer@0 35 sock.close();
samer@0 36 }
samer@0 37
samer@0 38
samer@0 39 static class Transfer implements Runnable {
samer@0 40 InputStream in;
samer@0 41 OutputStream out;
samer@0 42 byte [] buffer;
samer@0 43
samer@0 44 public Transfer(InputStream in, OutputStream out) {
samer@0 45 this.in=in;
samer@0 46 this.out=out;
samer@0 47 buffer=new byte[2048];
samer@0 48 }
samer@0 49
samer@0 50 public void run() {
samer@0 51 int n;
samer@0 52 try {
samer@0 53 do {
samer@0 54 n=in.read(buffer,0,2048);
samer@0 55 if (n>0) { out.write(buffer,0,n); out.flush(); }
samer@0 56 } while (n>=0);
samer@0 57 } catch (Exception ex) { ex.printStackTrace(); }
samer@0 58 System.err.println("reader thread terminating.");
samer@0 59 }
samer@0 60 }
samer@0 61
samer@0 62 public static void REPL(Socket call) throws Exception
samer@0 63 {
samer@0 64 Evaluator evaluator=Scheme.currentEvaluator();
samer@0 65
samer@0 66 PrintWriter oldout=evaluator.getOutput();
samer@0 67 PrintWriter olderr=evaluator.getError();
samer@0 68 PrintWriter newout=new PrintWriter(call.getOutputStream(),true);
samer@0 69 InputPort newin=new InputPort(new BufferedReader(
samer@0 70 new InputStreamReader(call.getInputStream())));
samer@0 71
samer@0 72
samer@0 73 oldout.println("... starting new remote REPL.");
samer@0 74 newout.println("Welcome to remote JVM - Type Ctrl-D to terminate session.");
samer@0 75
samer@0 76 // would like to replace System.err and System.out
samer@0 77 // with multicast streams
samer@0 78 evaluator.setOutput(newout);
samer@0 79 evaluator.setError(newout);
samer@0 80
samer@0 81 try {
samer@0 82 evaluator.readEvalWriteLoop("remote> ");
samer@0 83 /* Old version, can't work with jscheme 7.2
samer@0 84 Object x;
samer@0 85 while (!Scheme.EXIT) {
samer@0 86 try {
samer@0 87 newout.print("remote> "); newout.flush();
samer@0 88 if ((x = newin.read()) == InputPort.EOF) break;
samer@0 89 U.write(evaluator.eval(x), newout, true);
samer@0 90 newout.println(); newout.flush();
samer@0 91 } catch (Throwable e) { e.printStackTrace(newout); newout.flush(); }
samer@0 92 }
samer@0 93 */
samer@0 94 // try to let the other end know that the show's over
samer@0 95 call.shutdownInput();
samer@0 96 }
samer@0 97 finally {
samer@0 98 newout.println("Remote session terminated.");
samer@0 99 oldout.println("... remote REPL terminated.");
samer@0 100 evaluator.setOutput(oldout);
samer@0 101 evaluator.setError(olderr);
samer@0 102 evaluator.setExit(false); // remote session not allowed to terminate JVM!
samer@0 103 call.close(); // ?? or shutdownOutput();
samer@0 104 }
samer@0 105 }
samer@0 106 }