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));
     }
 
      /**