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 }
|