/*
* Copyright (c) 2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.management.backup.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.OutputStream;
/**
* An OutputStream wraps a child process, writing to this stream will writes to child process's STDIN.
* And closing this stream will also close child process and recycle all related resources.
* When closing this this stream, any output from child process's STDERR will be thrown as exception, and if
* child process exited with non-zero code, an exception will be thrown too.
*/
public class ProcessOutputStream extends OutputStream {
private static final Logger log = LoggerFactory.getLogger(ProcessOutputStream.class);
OutputStream stdinStream;
ProcessRunner processor;
StringBuilder errText = new StringBuilder();
public static final int ERROR_TEXT_MAX_LENGTH = 1024;
public ProcessOutputStream(ProcessRunner processor) {
this.processor = processor;
this.stdinStream = processor.getStdIn();
processor.captureAllTextInBackground(processor.getStdErr(), this.errText);
}
public ProcessOutputStream(Process childProcess) throws IOException {
this(new ProcessRunner(childProcess, true));
}
@Override
public void write(int b) throws IOException {
this.stdinStream.write(b);
}
@Override
public void write(byte b[]) throws IOException {
this.stdinStream.write(b);
}
@Override
public void write(byte b[], int off, int len) throws IOException {
this.stdinStream.write(b, off, len);
}
@Override
public void flush() throws IOException {
this.stdinStream.flush();
}
@Override
public void close() throws IOException {
if (this.stdinStream != null) {
this.stdinStream.close();
this.stdinStream = null;
}
if (this.processor != null) {
int exitCode = 0;
try {
exitCode = this.processor.join();
} catch (InterruptedException e) {
log.error("Interrupted when waiting for process", e);
}
this.processor.close();
this.processor = null;
if (exitCode != 0) {
throw new IOException(errText.length() > 0 ? errText.toString() : Integer.toString(exitCode));
}
}
}
}