summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RunExternalScriptTest.java40
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java78
2 files changed, 115 insertions, 3 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RunExternalScriptTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RunExternalScriptTest.java
index 82beab2dc8..b6a2519c59 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RunExternalScriptTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RunExternalScriptTest.java
@@ -52,6 +52,7 @@ import java.io.IOException;
import java.io.InputStream;
import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.util.FS.ExecutionResult;
import org.junit.Before;
import org.junit.Test;
@@ -163,6 +164,45 @@ public class RunExternalScriptTest {
assertEquals(127, rc);
}
+ @Test
+ public void testCopyStdInExecute()
+ throws IOException, InterruptedException {
+ String inputStr = "a\nb\rc\r\nd";
+ File script = writeTempFile("cat -");
+ ProcessBuilder pb = new ProcessBuilder("/bin/sh", script.getPath());
+ ExecutionResult res = FS.DETECTED.execute(pb,
+ new ByteArrayInputStream(inputStr.getBytes()));
+ assertEquals(0, res.getRc());
+ assertEquals(inputStr, new String(res.getStdout().toByteArray()));
+ assertEquals("", new String(res.getStderr().toByteArray()));
+ }
+
+ @Test
+ public void testStdErrExecute() throws IOException, InterruptedException {
+ File script = writeTempFile("echo hi >&2");
+ ProcessBuilder pb = new ProcessBuilder("/bin/sh", script.getPath());
+ ExecutionResult res = FS.DETECTED.execute(pb, null);
+ assertEquals(0, res.getRc());
+ assertEquals("", new String(res.getStdout().toByteArray()));
+ assertEquals("hi" + sep, new String(res.getStderr().toByteArray()));
+ }
+
+ @Test
+ public void testAllTogetherBinExecute()
+ throws IOException, InterruptedException {
+ String inputStr = "a\nb\rc\r\nd";
+ File script = writeTempFile(
+ "echo $#,$1,$2,$3,$4,$5,$6 >&2 ; cat -; exit 5");
+ ProcessBuilder pb = new ProcessBuilder("/bin/sh", script.getPath(), "a",
+ "b", "c");
+ ExecutionResult res = FS.DETECTED.execute(pb,
+ new ByteArrayInputStream(inputStr.getBytes()));
+ assertEquals(5, res.getRc());
+ assertEquals(inputStr, new String(res.getStdout().toByteArray()));
+ assertEquals("3,a,b,c,,," + sep,
+ new String(res.getStderr().toByteArray()));
+ }
+
private File writeTempFile(String body) throws IOException {
File f = File.createTempFile("RunProcessTestScript_", "");
JGitTestUtil.write(f, body);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index e407dd8be9..b61e47f5f6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -110,7 +110,54 @@ public abstract class FS {
}
}
- final static Logger LOG = LoggerFactory.getLogger(FS.class);
+ /**
+ * Result of an executed process. The caller is responsible to close the
+ * contained {@link TemporaryBuffer}s
+ *
+ * @since 4.2
+ */
+ public static class ExecutionResult {
+ private TemporaryBuffer stdout;
+
+ private TemporaryBuffer stderr;
+
+ private int rc;
+
+ /**
+ * @param stdout
+ * @param stderr
+ * @param rc
+ */
+ public ExecutionResult(TemporaryBuffer stdout, TemporaryBuffer stderr,
+ int rc) {
+ this.stdout = stdout;
+ this.stderr = stderr;
+ this.rc = rc;
+ }
+
+ /**
+ * @return buffered standard output stream
+ */
+ public TemporaryBuffer getStdout() {
+ return stdout;
+ }
+
+ /**
+ * @return buffered standard error stream
+ */
+ public TemporaryBuffer getStderr() {
+ return stderr;
+ }
+
+ /**
+ * @return the return code of the process
+ */
+ public int getRc() {
+ return rc;
+ }
+ }
+
+ private final static Logger LOG = LoggerFactory.getLogger(FS.class);
/** The auto-detected implementation selected for this operating system and JRE. */
public static final FS DETECTED = detect();
@@ -1004,10 +1051,10 @@ public abstract class FS {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
- if (!pool.awaitTermination(5, TimeUnit.SECONDS)) {
+ if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being canceled
- if (!pool.awaitTermination(5, TimeUnit.SECONDS))
+ if (!pool.awaitTermination(60, TimeUnit.SECONDS))
hasShutdown = false;
}
} catch (InterruptedException ie) {
@@ -1034,6 +1081,31 @@ public abstract class FS {
*/
public abstract ProcessBuilder runInShell(String cmd, String[] args);
+ /**
+ * Execute a command defined by a {@link ProcessBuilder}.
+ *
+ * @param pb
+ * The command to be executed
+ * @param in
+ * The standard input stream passed to the process
+ * @return The result of the executed command
+ * @throws InterruptedException
+ * @throws IOException
+ * @since 4.2
+ */
+ public ExecutionResult execute(ProcessBuilder pb, InputStream in)
+ throws IOException, InterruptedException {
+ TemporaryBuffer stdout = new TemporaryBuffer.LocalFile(null);
+ TemporaryBuffer stderr = new TemporaryBuffer.Heap(1024, 1024 * 1024);
+ try {
+ int rc = runProcess(pb, stdout, stderr, in);
+ return new ExecutionResult(stdout, stderr, rc);
+ } finally {
+ stdout.close();
+ stderr.close();
+ }
+ }
+
private static class Holder<V> {
final V value;