summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2017-12-10 18:10:25 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2017-12-10 18:10:34 +0100
commit032750acbfce756dd143f02ec09087e183ee4e6c (patch)
treea59079daa991fff8c85ccb8b5bbef49f34e1ae4d
parentcde32497b5399168ef0262075775eceaf4a57574 (diff)
parent7ccf38adc60c12606164655386630b4e296baf13 (diff)
downloadjgit-032750acbfce756dd143f02ec09087e183ee4e6c.tar.gz
jgit-032750acbfce756dd143f02ec09087e183ee4e6c.zip
Merge branch 'stable-4.9'
* stable-4.9: Fix IllegalThreadStateException if stderr closed without exiting Change-Id: I8a6a6788c2bb000171233b88d9592ed0640ad15e
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java33
3 files changed, 31 insertions, 6 deletions
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 481cebcaa2..b900306c32 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -122,6 +122,7 @@ classCastNotA=Not a {0}
cloneNonEmptyDirectory=Destination path "{0}" already exists and is not an empty directory
closed=closed
collisionOn=Collision on {0}
+commandClosedStderrButDidntExit=Command {0} closed stderr stream but didn''t exit within timeout {1} seconds
commandRejectedByHook=Rejected by "{0}" hook.\n{1}
commandWasCalledInTheWrongState=Command {0} was called in the wrong state
commitAlreadyExists=exists {0}
@@ -648,6 +649,7 @@ tagAlreadyExists=tag ''{0}'' already exists
tagNameInvalid=tag name {0} is invalid
tagOnRepoWithoutHEADCurrentlyNotSupported=Tag on repository without HEAD currently not supported
theFactoryMustNotBeNull=The factory must not be null
+threadInterruptedWhileRunning="Current thread interrupted while running {0}"
timeIsUncertain=Time is uncertain
timerAlreadyTerminated=Timer already terminated
tooManyCommands=Too many commands
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index 921c2dc17d..cc378832ff 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -181,6 +181,7 @@ public class JGitText extends TranslationBundle {
/***/ public String cloneNonEmptyDirectory;
/***/ public String closed;
/***/ public String collisionOn;
+ /***/ public String commandClosedStderrButDidntExit;
/***/ public String commandRejectedByHook;
/***/ public String commandWasCalledInTheWrongState;
/***/ public String commitAlreadyExists;
@@ -708,6 +709,7 @@ public class JGitText extends TranslationBundle {
/***/ public String tagOnRepoWithoutHEADCurrentlyNotSupported;
/***/ public String transactionAborted;
/***/ public String theFactoryMustNotBeNull;
+ /***/ public String threadInterruptedWhileRunning;
/***/ public String timeIsUncertain;
/***/ public String timerAlreadyTerminated;
/***/ public String tooManyCommands;
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 1be2ef8d01..03a05689e7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -564,6 +564,10 @@ public abstract class FS {
}
private static class GobblerThread extends Thread {
+
+ /* The process has 5 seconds to exit after closing stderr */
+ private static final int PROCESS_EXIT_TIMEOUT = 5;
+
private final Process p;
private final String desc;
private final String dir;
@@ -586,15 +590,16 @@ public abstract class FS {
err.append((char) ch);
}
} catch (IOException e) {
- if (p.exitValue() != 0) {
- setError(e, e.getMessage());
+ if (waitForProcessCompletion(e) && p.exitValue() != 0) {
+ setError(e, e.getMessage(), p.exitValue());
fail.set(true);
} else {
// ignore. command terminated faster and stream was just closed
+ // or the process didn't terminate within timeout
}
} finally {
- if (err.length() > 0) {
- setError(null, err.toString());
+ if (waitForProcessCompletion(null) && err.length() > 0) {
+ setError(null, err.toString(), p.exitValue());
if (p.exitValue() != 0) {
fail.set(true);
}
@@ -602,11 +607,27 @@ public abstract class FS {
}
}
- private void setError(IOException e, String message) {
+ @SuppressWarnings("boxing")
+ private boolean waitForProcessCompletion(IOException originalError) {
+ try {
+ if (!p.waitFor(PROCESS_EXIT_TIMEOUT, TimeUnit.SECONDS)) {
+ setError(originalError, MessageFormat.format(
+ JGitText.get().commandClosedStderrButDidntExit,
+ desc, PROCESS_EXIT_TIMEOUT), -1);
+ fail.set(true);
+ }
+ } catch (InterruptedException e) {
+ LOG.error(MessageFormat.format(
+ JGitText.get().threadInterruptedWhileRunning, desc), e);
+ }
+ return false;
+ }
+
+ private void setError(IOException e, String message, int exitCode) {
exception.set(e);
errorMessage.set(MessageFormat.format(
JGitText.get().exceptionCaughtDuringExcecutionOfCommand,
- desc, dir, Integer.valueOf(p.exitValue()), message));
+ desc, dir, Integer.valueOf(exitCode), message));
}
}