comparison src/samer/silk/Terminal.java @ 0:bf79fb79ee13

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