/*******************************************************************************
* Copyright (c) 2011, 2016 Eurotech and/or its affiliates
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eurotech
*******************************************************************************/
package org.eclipse.kura.deployment.rp.sh.impl;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Timer;
public class ProcessMonitorThread extends Thread {
private final Process proc;
private final String stdin;
private final int procTout;
private String stdout;
private String stderr;
private boolean timedOut;
private Exception exception;
private Integer exitValue;
public ProcessMonitorThread(Process proc, String stdin, int procTout) {
this.proc = proc;
this.stdin = stdin;
this.procTout = procTout;
this.timedOut = false;
}
public String getStdout() {
return this.stdout;
}
public String getStderr() {
return this.stderr;
}
public Integer getExitValue() {
return this.exitValue;
}
public boolean isTimedOut() {
return this.timedOut;
}
public Exception getException() {
return this.exception;
}
public void setException(Exception exception) {
this.exception = exception;
}
@Override
public void run() {
// Resources that should be cleaned up
InputStream is = null;
InputStream es = null;
OutputStream os = null;
BufferedWriter obw = null;
StreamGobbler isg = null;
StreamGobbler esg = null;
Timer timer = null;
try {
if (this.procTout > 0) {
timer = new Timer(true);
InterruptTimerTask interrupter = new InterruptTimerTask(Thread.currentThread());
timer.schedule(interrupter, this.procTout /* seconds */ * 1000 /* milliseconds per second */);
}
is = this.proc.getInputStream();
es = this.proc.getErrorStream();
os = this.proc.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
obw = new BufferedWriter(osw);
// Spawn a couple of StreamGobbler to consume output streams
isg = new StreamGobbler(is, "stdout");
esg = new StreamGobbler(es, "stderr");
isg.start();
esg.start();
if (this.stdin != null) {
try {
obw.write(this.stdin);
obw.newLine();
obw.flush();
} catch (IOException e) {
throw e;
}
}
this.proc.waitFor();
isg.join(1000);
esg.join(1000);
this.exitValue = this.proc.exitValue();
} catch (IOException e) {
this.exception = e;
} catch (InterruptedException e) {
this.timedOut = true;
} finally {
if (timer != null) {
timer.cancel();
}
if (isg != null) {
isg.interrupt();
try {
isg.join(1000);
} catch (InterruptedException e) {
// Ignore
}
this.stdout = isg.getStreamAsString();
}
if (esg != null) {
esg.interrupt();
try {
esg.join(1000);
} catch (InterruptedException e) {
// Ignore
}
this.stderr = esg.getStreamAsString();
}
// See http://kylecartmell.com/?p=9
if (is != null) {
try {
is.close();
} catch (IOException e) {
// Ignore
}
}
if (es != null) {
try {
es.close();
} catch (IOException e) {
// Ignore
}
}
if (obw != null) {
try {
obw.close();
} catch (IOException e) {
// Ignore
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Ignore
}
}
if (this.proc != null) {
this.proc.destroy();
}
Thread.interrupted(); // See http://kylecartmell.com/?p=9
}
}
}