Fixing bugs and cleaning up: Continuing sub-graph executions when there is no matched...
[jpf-core.git] / src / main / gov / nasa / jpf / listener / LogConsole.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.listener;
19
20 import java.io.BufferedReader;
21 import java.io.IOException;
22 import java.io.InputStreamReader;
23 import java.net.ServerSocket;
24 import java.net.Socket;
25
26 /**
27  * simple logging facility that listens on a socket (e.g. for log output display)
28  */
29 public class LogConsole {
30   
31   static int DEF_PORT = 20000; // keep this in sync with the gov.nasa.jpf.util.LogHandler
32   
33   class ShutdownHook implements Runnable {
34     @Override
35         public void run () {
36       if (running) {
37         // not very threadsafe, but worst thing that can happen is we close twice
38         killed = true;
39         System.out.println("\nLogConsole killed, shutting down");
40       }
41       try {
42         cs.close();
43         ss.close();
44       } catch (Throwable t) {
45         // not much we can do here anyway
46       }
47     }
48   }
49   
50   
51   boolean running;
52   
53   int port;
54   boolean autoclose;
55   boolean killed;
56   
57   ServerSocket ss;
58   Socket cs;
59   
60   public void run () {
61     running = true;
62     Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
63     
64     if (port == 0) {
65       port = DEF_PORT;
66     }
67     
68     try {
69       ss = new ServerSocket(port);
70       
71       try {          
72         do {
73           System.out.println("LogConsole listening on port: " + port);
74
75           cs = ss.accept();
76           BufferedReader in = new BufferedReader( new InputStreamReader(cs.getInputStream()));
77           String msg; 
78           
79           System.out.println("LogConsole connected");
80           System.out.println("--------------------------------------------------------------------------------");
81           try {
82             
83             while ((msg = in.readLine()) != null) {
84               System.out.println(msg);
85             }
86             
87             System.out.println("--------------------------------------------------------------------------------");            
88             System.out.println("LogConsole disconnected");
89           } catch (IOException iox) {
90             System.err.println(iox);
91           }
92
93           in.close();
94           cs.close();
95         } while (!autoclose);
96
97         System.out.println("LogConsole closing");
98         
99       } catch (IOException iox) {
100         if (!killed) {
101           System.err.println("Error: LogConsole accept failed on port: " + port);
102         }
103       }
104       
105     } catch (IOException iox) {
106       System.err.println("Error: LogConsole cannot listen on port: " + port);
107     }
108     
109     running = false;
110   }
111
112   public void showUsage () {
113     System.out.println("LogConsole: socket based console logger");
114     System.out.println("     usage: java gov.nasa.jpf.tools.LogConsole {flags} [<port>]");
115     System.out.println("      args: -help         show this message");
116     System.out.println("            -autoclose    close the application upon disconnect");
117     System.out.println("            <port>        optional port number, default: " + DEF_PORT);
118   }
119   
120   boolean processArgs (String[] args) {
121     for (int i=0; i<args.length; i++) {
122       if (args[i].charAt(0) == '-') {
123         if (args[i].equals("-autoclose")) {
124           args[i] = null;
125           autoclose = true;
126         } else if (args[i].equals("-help")) {
127           showUsage();
128           return false;
129         } else {
130           System.err.println("Warning: unknown argument (see -help for usage): " + args[i]);
131         }
132       } else {
133         if (args[i].matches("[0-9]+")) {
134           if (port != 0) {
135             System.err.println("Error: only one port parameter allowed (see -help for usage): " + args[i]);
136             return false;
137           }
138           
139           try {
140             port = Integer.parseInt(args[i]);
141           } catch (NumberFormatException nfx) {
142             System.err.println("Error: illegal port spec: " + args[i]);
143             return false;
144           }
145         } else {
146           System.out.println("Error: unknown argument: " + args[i]);
147           return false;
148         }
149       }
150     }
151     
152     return true;
153   }
154
155   public static void main (String[] args) {
156     LogConsole console = new LogConsole();
157     
158     if (console.processArgs(args)) {
159       console.run();
160     }
161   }
162 }