Fix input redirection

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1736000 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/gogo/runtime/pom.xml b/gogo/runtime/pom.xml
index 00b1635..90b83b2 100644
--- a/gogo/runtime/pom.xml
+++ b/gogo/runtime/pom.xml
@@ -84,6 +84,13 @@
                     </instructions>
                 </configuration>
             </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 </project>
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Pipe.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Pipe.java
index eb2bf81..6b01470 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Pipe.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Pipe.java
@@ -78,7 +78,7 @@
     private static final int READ = 1;
     private static final int WRITE = 2;
 
-    private void setStream(Channel ch, int fd, int readWrite) throws IOException {
+    private void setStream(Channel ch, int fd, int readWrite, boolean begOfPipe, boolean endOfPipe) throws IOException {
         if ((readWrite & READ) != 0 && !(ch instanceof ReadableByteChannel)) {
             throw new IllegalArgumentException("Channel is not readable");
         }
@@ -106,7 +106,13 @@
                     mrbc = (MultiReadableByteChannel) streams[fd];
                 } else {
                     mrbc = new MultiReadableByteChannel();
-                    mrbc.addChannel((ReadableByteChannel) streams[fd], toclose[fd]);
+                    if (streams[fd] != null && begOfPipe) {
+                        if (toclose[fd]) {
+                            streams[fd].close();
+                        }
+                    } else {
+                        mrbc.addChannel((ReadableByteChannel) streams[fd], toclose[fd]);
+                    }
                     streams[fd] = mrbc;
                     toclose[fd] = true;
                 }
@@ -117,7 +123,13 @@
                     mrbc = (MultiWritableByteChannel) streams[fd];
                 } else {
                     mrbc = new MultiWritableByteChannel();
-                    mrbc.addChannel((WritableByteChannel) streams[fd], toclose[fd]);
+                    if (streams[fd] != null && endOfPipe) {
+                        if (toclose[fd]) {
+                            streams[fd].close();
+                        }
+                    } else {
+                        mrbc.addChannel((WritableByteChannel) streams[fd], toclose[fd]);
+                    }
                     streams[fd] = mrbc;
                     toclose[fd] = true;
                 }
@@ -196,6 +208,11 @@
         WritableByteChannel errChannel = (WritableByteChannel) streams[2];
 
         Channel[] prevStreams = tStreams.get();
+
+        // TODO: not sure this is the correct way
+        boolean begOfPipe = !toclose[0];
+        boolean endOfPipe = !toclose[1];
+
         try
         {
             if (executable instanceof Statement) {
@@ -227,10 +244,10 @@
                         }
                         Channel ch = Files.newByteChannel(outPath, options);
                         if (fd >= 0) {
-                            setStream(ch, fd, WRITE);
+                            setStream(ch, fd, WRITE, begOfPipe, endOfPipe);
                         } else {
-                            setStream(ch, 1, WRITE);
-                            setStream(ch, 2, WRITE);
+                            setStream(ch, 1, WRITE, begOfPipe, endOfPipe);
+                            setStream(ch, 2, WRITE, begOfPipe, endOfPipe);
                         }
                     }
                     else if ((m = Pattern.compile("([0-9])?>&([0-9])").matcher(t)).matches()) {
@@ -262,7 +279,7 @@
                             options.add(StandardOpenOption.CREATE);
                         }
                         Channel ch = Files.newByteChannel(inPath, options);
-                        setStream(ch, fd, READ + (output ? WRITE : 0));
+                        setStream(ch, fd, READ + (output ? WRITE : 0), begOfPipe, endOfPipe);
                     }
                 }
             } else {
@@ -271,9 +288,6 @@
 
             tStreams.set(streams);
 
-            // TODO: not sure this is the correct way
-            boolean endOfPipe = !toclose[1];
-
             in = Channels.newInputStream((ReadableByteChannel) streams[0]);
             out = new PrintStream(Channels.newOutputStream((WritableByteChannel) streams[1]), true);
             err = new PrintStream(Channels.newOutputStream((WritableByteChannel) streams[2]), true);
diff --git a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/TestParser4.java b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/TestParser4.java
index 0adb31a..210d067 100644
--- a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/TestParser4.java
+++ b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/TestParser4.java
@@ -21,6 +21,7 @@
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.Reader;
 import java.io.StringWriter;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -41,8 +42,8 @@
         c.addCommand("echoerr", this);
         c.addCommand("tac", this);
 
-        assertEquals("hello", c.execute("echo | tac"));
-        assertEquals("hello", c.execute("echoerr |& tac"));
+        assertEquals("hello\n", c.execute("echo hello| tac"));
+        assertEquals("hello\n", c.execute("echoerr hello|& tac"));
     }
 
     public void testRedir() throws Exception {
@@ -55,31 +56,70 @@
         c.currentDir(path);
 
         Files.deleteIfExists(path.resolve("foo"));
-        assertEquals("hello", c.execute("echo >foo | tac"));
+        assertEquals("hello\n", c.execute("echo hello>foo | tac"));
         assertEquals("hello\n", new String(Files.readAllBytes(path.resolve("foo"))));
     }
 
-    public void echo()
-    {
-        System.out.println("hello");
+    public void testRedirInput() throws Exception {
+        Context c = new Context();
+        c.addCommand("echo", this);
+        c.addCommand("tac", this);
+        c.addCommand("cat", this);
+
+        Path path = Paths.get("target/tmp");
+        Files.createDirectories(path);
+        c.currentDir(path);
+
+        Files.deleteIfExists(path.resolve("fooa"));
+        Files.deleteIfExists(path.resolve("foob"));
+        c.execute("echo a>fooa");
+        c.execute("echo b>foob");
+        assertEquals("a\nb\n", c.execute("cat <fooa <foob | tac"));
     }
 
-    public void echoerr()
+    public void testMultiInput() throws Exception {
+        Context c = new Context();
+        c.addCommand("echo", this);
+        c.addCommand("tac", this);
+        c.addCommand("cat", this);
+
+        Path path = Paths.get("target/tmp");
+        Files.createDirectories(path);
+        c.currentDir(path);
+
+        Files.deleteIfExists(path.resolve("fooa"));
+        Files.deleteIfExists(path.resolve("foob"));
+        c.execute("echo a>fooa");
+        c.execute("echo b>foob");
+        assertEquals("foo\na\nb\n", c.execute("echo foo | cat <fooa | cat<foob | tac"));
+    }
+
+    public void echo(String msg)
     {
-        System.err.println("hello");
+        System.out.println(msg);
+    }
+
+    public void echoerr(String msg)
+    {
+        System.err.println(msg);
+    }
+
+    public void cat() throws IOException {
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                System.out.println(line);
+            }
+        }
     }
 
     public String tac() throws IOException {
         StringWriter sw = new StringWriter();
-        BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
-        boolean first = true;
-        String s;
-        while ((s = rdr.readLine()) != null) {
-            if (!first) {
-                sw.write(' ');
-            }
-            first = false;
-            sw.write(s);
+        Reader rdr = new InputStreamReader(System.in);
+        char[] buf = new char[1024];
+        int len;
+        while ((len = rdr.read(buf)) >= 0) {
+            sw.write(buf, 0, len);
         }
         return sw.toString();
     }