1
/*******************************************************************************
2
* Copyright (c) 2000, 2008 IBM Corporation and others.
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 - initial API and implementation
10
*******************************************************************************/
12
package org.eclipse.cdt.internal.core;
14
import java.io.BufferedReader;
15
import java.io.IOException;
16
import java.io.InputStream;
17
import java.io.InputStreamReader;
18
import java.io.OutputStream;
21
* Bundled state of a launched process including the threads linking the process
22
* in/output to console documents.
24
public class ProcessClosure {
27
* Thread which continuously reads from a input stream and pushes the read
28
* data to an output stream which is immediately flushed afterwards.
30
protected static class ReaderThread extends Thread {
32
private InputStream fInputStream;
33
private OutputStream fOutputStream;
34
private boolean fFinished = false;
35
private String lineSeparator;
37
* outputStream can be null
39
public ReaderThread(ThreadGroup group, String name, InputStream in, OutputStream out) {
44
lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
51
BufferedReader reader = new BufferedReader(new InputStreamReader(fInputStream));
53
while ((line = reader.readLine()) != null) {
54
line += lineSeparator;
55
fOutputStream.write(line.getBytes());
57
} catch (IOException x) {
62
fOutputStream.flush();
63
} catch (IOException e) {
68
} catch (IOException e) {
77
public synchronized boolean finished() {
81
public synchronized void waitFor() {
85
} catch (InterruptedException e) {
90
public synchronized void complete() {
97
fOutputStream.close();
98
} catch (IOException e) {
104
protected static int fCounter = 0;
106
protected Process fProcess;
108
protected OutputStream fOutput;
109
protected OutputStream fError;
111
protected ReaderThread fOutputReader;
112
protected ReaderThread fErrorReader;
115
* Creates a process closure and connects the launched process with a
118
* @param outputStream
119
* prcess stdout is written to this stream. Can be
120
* <code>null</code>, if not interested in reading the output
122
* prcess stderr is written to this stream. Can be
123
* <code>null</code>, if not interested in reading the output
125
public ProcessClosure(Process process, OutputStream outputStream, OutputStream errorStream) {
127
fOutput = outputStream;
128
fError = errorStream;
132
* Live links the launched process with the configured in/out streams using
135
public void runNonBlocking() {
136
ThreadGroup group = new ThreadGroup("CBuilder" + fCounter++); //$NON-NLS-1$
138
InputStream stdin = fProcess.getInputStream();
139
InputStream stderr = fProcess.getErrorStream();
141
fOutputReader = new ReaderThread(group, "OutputReader", stdin, fOutput); //$NON-NLS-1$
142
fErrorReader = new ReaderThread(group, "ErrorReader", stderr, fError); //$NON-NLS-1$
144
fOutputReader.start();
145
fErrorReader.start();
148
public void runBlocking() {
151
boolean finished = false;
155
} catch (InterruptedException e) {
156
//System.err.println("Closure exception " +e);
159
fProcess.exitValue();
161
} catch (IllegalThreadStateException e) {
162
//System.err.println("Closure exception " +e);
166
// @@@FIXME: Windows 2000 is screwed; double-check using output threads
167
if (!fOutputReader.finished()) {
168
fOutputReader.waitFor();
171
if (!fErrorReader.finished()) {
172
fErrorReader.waitFor();
175
fOutputReader.close();
176
fErrorReader.close();
177
// it seems that thread termination and stream closing is working
181
fOutputReader = null;
185
public boolean isAlive() {
186
if (fProcess != null) {
187
if (fOutputReader.isAlive() || fErrorReader.isAlive()) {
191
fOutputReader.close();
192
fErrorReader.close();
193
fOutputReader = null;
200
* The same functionality as "isAlive()"
201
* but does not affect out streams,
202
* because they can be shared among processes
204
public boolean isRunning() {
205
if (fProcess != null) {
206
if (fOutputReader.isAlive() || fErrorReader.isAlive()) {
214
* Forces the termination the launched process
216
public void terminate() {
217
if (fProcess != null) {
221
if (!fOutputReader.finished()) {
222
fOutputReader.waitFor();
224
if (!fErrorReader.finished()) {
225
fErrorReader.waitFor();
227
fOutputReader.close();
228
fErrorReader.close();
229
fOutputReader = null;