Browse Source

FS#runProcess: Fix OutputStream left unclosed after IOException

The runProcess method creates an OutputStream that is not managed by
a try-with-resource because it's manually closed and any IOException
raised by the close() method is explicitly ignored.

Suppress the resource warning with an explanatory comment.

Enclose the call to StreamGobbler#copy in an inner try-block, and move
the call to close() inside its finally block. This prevents the stream
from being left unclosed if StreamGobbler#copy raises IOException.

Change-Id: Idca9adfc4d87e0989d787ad8239c055c0c849814
Signed-off-by: David Pursehouse <david.pursehouse@gmail.com>
stable-5.0
David Pursehouse 7 years ago committed by Matthias Sohn
parent
commit
76b4ed6a85
  1. 26
      org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java

26
org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java

@ -1108,19 +1108,23 @@ public abstract class FS {
new StreamGobbler(process.getErrorStream(), errRedirect)); new StreamGobbler(process.getErrorStream(), errRedirect));
executor.execute( executor.execute(
new StreamGobbler(process.getInputStream(), outRedirect)); new StreamGobbler(process.getInputStream(), outRedirect));
@SuppressWarnings("resource") // Closed in the finally block
OutputStream outputStream = process.getOutputStream(); OutputStream outputStream = process.getOutputStream();
if (inRedirect != null) {
new StreamGobbler(inRedirect, outputStream).copy();
}
try { try {
outputStream.close(); if (inRedirect != null) {
} catch (IOException e) { new StreamGobbler(inRedirect, outputStream).copy();
// When the process exits before consuming the input, the OutputStream }
// is replaced with the null output stream. This null output stream } finally {
// throws IOException for all write calls. When StreamGobbler fails to try {
// flush the buffer because of this, this close call tries to flush it outputStream.close();
// again. This causes another IOException. Since we ignore the } catch (IOException e) {
// IOException in StreamGobbler, we also ignore the exception here. // When the process exits before consuming the input, the OutputStream
// is replaced with the null output stream. This null output stream
// throws IOException for all write calls. When StreamGobbler fails to
// flush the buffer because of this, this close call tries to flush it
// again. This causes another IOException. Since we ignore the
// IOException in StreamGobbler, we also ignore the exception here.
}
} }
return process.waitFor(); return process.waitFor();
} catch (IOException e) { } catch (IOException e) {

Loading…
Cancel
Save