1
/*******************************************************************************
2
* Copyright (c) 2006 IBM Corporation.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* IBM Corporation - Jeff Briggs, Henry Hughes, Ryan Morse
10
*******************************************************************************/
12
package org.eclipse.linuxtools.systemtap.ui.structures.runnable;
14
import java.io.IOException;
15
import java.io.PrintWriter;
16
import java.util.ArrayList;
18
import org.eclipse.linuxtools.internal.systemtap.ui.structures.Localization;
19
import org.eclipse.linuxtools.systemtap.ui.structures.IPasswordPrompt;
20
import org.eclipse.linuxtools.systemtap.ui.structures.listeners.IGobblerListener;
25
* A class to spawn a separate thread to run a <code>Process</code>.
28
public class Command implements Runnable {
30
* Bug in the exec command prevents using a single string. Forced
31
* to use a workaround in order to run commands with spaces.
33
* http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4365120
34
* http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4109888
38
* Spawns the new thread that this class will run in. From the Runnable
39
* interface spawning the new thread automatically calls the run() method.
40
* This must be called by the implementing class in order to start the
42
* @param cmd The entire command to run
43
* @param envVars List of all environment variables to use
44
* @param prompt The password promt for allowing the user to enter their password.
45
* @param monitorDelay The time in MS to wait between checking whether the <code>Process</code> has finished.
47
public Command(String[] cmd, String[] envVars, IPasswordPrompt prompt, int monitorDelay) {
49
this.envVars = envVars;
51
this.monitorDelay = monitorDelay;
55
* Spawns the new thread that this class will run in. From the Runnable
56
* interface spawning the new thread automatically calls the run() method.
57
* This must be called by the implementing class in order to start the
59
* @param cmd The entire command to run
60
* @param envVars List of all environment variables to use
61
* @param prompt The password promt for allowing the user to enter their password.
63
public Command(String[] cmd, String[] envVars, IPasswordPrompt prompt) {
64
this(cmd, envVars, prompt, 100);
68
* Starts the <code>Thread</code> that the new <code>Process</code> will run in.
69
* This must be called in order to get the process to start running.
73
Thread t = new Thread(this, cmd[0]);
77
returnVal = Integer.MIN_VALUE;
82
* Starts up the process that will execute the provided command and registers
83
* the <code>StreamGobblers</code> with their respective streams.
85
protected boolean init() {
87
process = Runtime.getRuntime().exec(cmd, envVars);
89
errorGobbler = new StreamGobbler(process.getErrorStream());
90
inputGobbler = new StreamGobbler(process.getInputStream());
93
for(i=0; i<inputListeners.size(); i++)
94
inputGobbler.addDataListener(inputListeners.get(i));
95
for(i=0; i<errorListeners.size(); i++)
96
errorGobbler.addDataListener(errorListeners.get(i));
98
} catch(IOException ioe) {}
103
* This method handles checking the status of the running <code>Process</code>. It
104
* is called when the new Thread is created, and thus should never be called by
105
* any implementing program. To run call the <code>start</code> method.
108
errorGobbler.start();
109
inputGobbler.start();
114
if(null != errorGobbler && errorGobbler.readLine().endsWith(Localization.getString("Command.Password"))) {
115
PrintWriter writer = new PrintWriter(process.getOutputStream(), true);
116
writer.println(prompt.getPassword());
119
returnVal = process.exitValue(); //Dont care what the value is, just whether it throws an exception
120
stop(); //Above line will throw an exception if not finished
121
} catch(IllegalThreadStateException itse) {}
124
Thread.sleep(monitorDelay);
126
} catch(InterruptedException ie) {
127
} catch(NullPointerException npe) {}
131
* Stops the process from running and stops the <code>StreamGobblers</code> from monitering
134
public synchronized void stop() {
137
if(null != errorGobbler)
139
if(null != inputGobbler)
147
* Method to check whether or not the process in running.
148
* @return The execution status.
150
public boolean isRunning() {
155
* Method to check if this class has already been disposed.
156
* @return Status of the class.
158
public boolean isDisposed() {
163
* The return value of the process.
164
* 2^231-1 if the process is still running.
165
* -2^231 if there was an error creating the process
166
* @return The return value generated from running the provided command.
168
public int getReturnValue() {
173
* Registers the provided <code>IGobblerListener</code> with the InputStream
174
* @param listener A listener to monitor the InputStream from the Process
176
public void addInputStreamListener(IGobblerListener listener) {
177
if(null != inputGobbler)
178
inputGobbler.addDataListener(listener);
180
inputListeners.add(listener);
184
* Registers the provided <code>IGobblerListener</code> with the ErrorStream
185
* @param listener A listener to monitor the ErrorStream from the Process
187
public void addErrorStreamListener(IGobblerListener listener) {
188
if(null != errorGobbler)
189
errorGobbler.addDataListener(listener);
191
errorListeners.add(listener);
195
* Returns the list of everything that is listening the the InputStream
196
* @return List of all <code>IGobblerListeners</code> that are monitoring the stream.
199
public ArrayList<IGobblerListener> getInputStreamListeners() {
200
if(null != inputGobbler)
201
return inputListeners;
203
ArrayList<IGobblerListener> dataListeners = inputGobbler.getDataListeners();
204
return dataListeners;
209
* Returns the list of everything that is listening the the ErrorStream
210
* @return List of all <code>IGobblerListeners</code> that are monitoring the stream.
213
public ArrayList<IGobblerListener> getErrorStreamListeners() {
214
if(null != errorGobbler)
215
return errorListeners;
217
return errorGobbler.getDataListeners();
221
* Removes the provided listener from those monitoring the InputStream.
222
* @param listener An </code>IGobblerListener</code> that is monitoring the stream.
224
public void removeInputStreamListener(IGobblerListener listener) {
225
if(null != inputGobbler)
226
inputGobbler.removeDataListener(listener);
228
inputListeners.remove(listener);
232
* Removes the provided listener from those monitoring the ErrorStream.
233
* @param listener An </code>IGobblerListener</code> that is monitoring the stream.
235
public void removeErrorStreamListener(IGobblerListener listener) {
236
if(null != errorGobbler)
237
errorGobbler.removeDataListener(listener);
239
errorListeners.remove(listener);
243
* Disposes of all internal components of this class. Nothing in the class should be
244
* referenced after this is called.
246
public void dispose() {
250
inputListeners = null;
251
errorListeners = null;
253
if(null != inputGobbler)
254
inputGobbler.dispose();
257
if(null != errorGobbler)
258
errorGobbler.dispose();
263
private boolean stopped = false;
264
private boolean disposed = false;
265
private StreamGobbler inputGobbler = null;
266
private StreamGobbler errorGobbler = null;
267
private ArrayList<IGobblerListener> inputListeners = new ArrayList<IGobblerListener>(); //Only used to allow adding listeners before creating the StreamGobbler
268
private ArrayList<IGobblerListener> errorListeners = new ArrayList<IGobblerListener>(); //Only used to allow adding listeners before creating the StreamGobbler
269
private int returnVal = Integer.MAX_VALUE;
271
private String[] cmd;
272
private String[] envVars;
273
private IPasswordPrompt prompt;
274
private int monitorDelay;
275
protected Process process;
277
public static final int ERROR_STREAM = 0;
278
public static final int INPUT_STREAM = 1;
b'\\ No newline at end of file'