You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by sg...@apache.org on 2009/04/30 23:57:04 UTC
svn commit: r770463 - in /commons/proper/exec/trunk/src: changes/changes.xml
main/java/org/apache/commons/exec/InputStreamPumper.java
main/java/org/apache/commons/exec/PumpStreamHandler.java
test/java/org/apache/commons/exec/DefaultExecutorTest.java
Author: sgoeschl
Date: Thu Apr 30 21:57:03 2009
New Revision: 770463
URL: http://svn.apache.org/viewvc?rev=770463&view=rev
Log:
[EXEC-33] Copies all data from an System.input stream to an output stream of the executed process
Added:
commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/InputStreamPumper.java
Modified:
commons/proper/exec/trunk/src/changes/changes.xml
commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java
commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
Modified: commons/proper/exec/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/changes/changes.xml?rev=770463&r1=770462&r2=770463&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/changes/changes.xml (original)
+++ commons/proper/exec/trunk/src/changes/changes.xml Thu Apr 30 21:57:03 2009
@@ -23,6 +23,12 @@
<author email="sgoeschl@apache.org">Siegfried Goeschl</author>
</properties>
<body>
+ <release version="1.1-SNAPSHOT" date="as in SVN" description="Maintenance Release">
+ <action dev="sgoeschl" type="fix" due-to="Milos Kleint" issue="EXEC-33">
+ Copies all data from an System.input stream to an output stream of
+ the executed process.
+ </action>
+ </release>
<release version="1.0" date="2009-03-15" description="First Public Release">
<action dev="sgoeschl" type="fix" due-to="Sebastien Bazley" issue="EXEC-37">
Removed useless synchronized statement in
Added: commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/InputStreamPumper.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/InputStreamPumper.java?rev=770463&view=auto
==============================================================================
--- commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/InputStreamPumper.java (added)
+++ commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/InputStreamPumper.java Thu Apr 30 21:57:03 2009
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import org.apache.commons.exec.util.DebugUtils;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Copies all data from an System.input stream to an output stream of the executed process.
+ *
+ * @author mkleint
+ */
+public class InputStreamPumper implements Runnable {
+
+ public static final int SLEEPING_TIME = 100;
+
+ /** the input stream to pump from */
+ private final InputStream is;
+
+ /** the output stream to pmp into */
+ private final OutputStream os;
+
+ /** flag to stop the stream pumping */
+ private volatile boolean stop;
+
+
+ /**
+ * Create a new stream pumper.
+ *
+ * @param is input stream to read data from
+ * @param os output stream to write data to.
+ */
+ public InputStreamPumper(final InputStream is, final OutputStream os) {
+ this.is = is;
+ this.os = os;
+ }
+
+
+ /**
+ * Copies data from the input stream to the output stream. Terminates as
+ * soon as the input stream is closed or an error occurs.
+ */
+ public void run() {
+ stop = false;
+
+ try {
+ while (!stop) {
+ while (is.available() > 0 && !stop) {
+ os.write(is.read());
+ }
+ os.flush();
+ Thread.sleep(SLEEPING_TIME);
+ }
+ } catch (Exception e) {
+ String msg = "Got exception while reading/writing the stream";
+ DebugUtils.handleException(msg ,e);
+ } finally {
+ }
+ }
+
+
+ public void stopProcessing() {
+ stop = true;
+ }
+
+}
Modified: commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java?rev=770463&r1=770462&r2=770463&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java (original)
+++ commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java Thu Apr 30 21:57:03 2009
@@ -43,6 +43,8 @@
private final InputStream input;
+ private InputStreamPumper inputStreamPumper;
+
/**
* Construct a new <CODE>PumpStreamHandler</CODE>.
*
@@ -56,12 +58,6 @@
public PumpStreamHandler(final OutputStream out, final OutputStream err,
final InputStream input) {
- // see EXEC-33
- if(input == System.in) {
- String msg = "Using System.in is currently not supported since it would hang your application (see EXEC-33).";
- throw new IllegalArgumentException(msg);
- }
-
this.out = out;
this.err = err;
this.input = input;
@@ -131,8 +127,11 @@
*/
public void setProcessInputStream(final OutputStream os) {
if (input != null) {
- inputThread = createPump(input, os, true);
+ if (input == System.in) {
+ inputThread = createSystemInPump(input, os);
} else {
+ inputThread = createPump(input, os, true);
+ } } else {
try {
os.close();
} catch (IOException e) {
@@ -180,6 +179,10 @@
}
}
+ if (inputStreamPumper != null) {
+ inputStreamPumper.stopProcessing();
+ }
+
if (inputThread != null) {
try {
inputThread.join();
@@ -280,4 +283,20 @@
result.setDaemon(true);
return result;
}
+
+
+ /**
+ * Creates a stream pumper to copy the given input stream to the given
+ * output stream.
+ *
+ * @param is the System.in input stream to copy from
+ * @param os the output stream to copy into
+ * @return the stream pumper thread
+ */
+ private Thread createSystemInPump(InputStream is, OutputStream os) {
+ inputStreamPumper = new InputStreamPumper(is, os);
+ final Thread result = new Thread(inputStreamPumper);
+ result.setDaemon(true);
+ return result;
+ }
}
Modified: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java?rev=770463&r1=770462&r2=770463&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java (original)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java Thu Apr 30 21:57:03 2009
@@ -372,23 +372,16 @@
}
/**
- * Start a process and connect stdin, stdout and stderr. This
- * test currenty hang. Therefore we throw an IllegalArgument
- * Exception to notify the user (see EXEC-33).
+ * Start a process and connect stdin, stdout and stderr (see EXEC-33).
*/
public void testExecuteWithStdin() throws Exception
{
- try {
- CommandLine cl = new CommandLine(testScript);
- PumpStreamHandler pumpStreamHandler = new PumpStreamHandler( System.out, System.err, System.in );
- DefaultExecutor executor = new DefaultExecutor();
- executor.setStreamHandler( pumpStreamHandler );
- int exitValue = executor.execute(cl);
- assertFalse(exec.isFailure(exitValue));
- }
- catch(IllegalArgumentException e) {
- assertTrue( e.getMessage().indexOf("EXEC-33") >= 0);
- }
+ CommandLine cl = new CommandLine(testScript);
+ PumpStreamHandler pumpStreamHandler = new PumpStreamHandler( System.out, System.err, System.in );
+ DefaultExecutor executor = new DefaultExecutor();
+ executor.setStreamHandler( pumpStreamHandler );
+ int exitValue = executor.execute(cl);
+ assertFalse(exec.isFailure(exitValue));
}
/**