diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java index c69304243..d4d4f5412 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008-2010, Google Inc. * Copyright (C) 2008, Marek Zawirski * Copyright (C) 2008, Robin Rosenberg * Copyright (C) 2008, Shawn O. Pearce @@ -46,6 +47,7 @@ package org.eclipse.jgit.transport; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; @@ -142,15 +144,13 @@ public class TransportGitSsh extends SshTransport implements PackTransport { return cmd.toString(); } - ChannelExec exec(final String exe, final OutputStream err) - throws TransportException { + ChannelExec exec(final String exe) throws TransportException { initSession(); final int tms = getTimeout() > 0 ? getTimeout() * 1000 : 0; try { final ChannelExec channel = (ChannelExec) sock.openChannel("exec"); channel.setCommand(commandFor(exe)); - channel.setErrStream(err); channel.connect(tms); return channel; } catch (JSchException je) { @@ -224,6 +224,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport { class SshFetchConnection extends BasePackFetchConnection { private ChannelExec channel; + private Thread errorThread; + private int exitStatus; SshFetchConnection() throws TransportException { @@ -231,12 +233,16 @@ public class TransportGitSsh extends SshTransport implements PackTransport { try { final MessageWriter msg = new MessageWriter(); setMessageWriter(msg); - channel = exec(getOptionUploadPack(), msg.getRawStream()); - if (channel.isConnected()) - init(channel.getInputStream(), outputStream(channel)); - else - throw new TransportException(uri, getMessages()); + channel = exec(getOptionUploadPack()); + if (!channel.isConnected()) + throw new TransportException(uri, "connection failed"); + + final InputStream upErr = channel.getErrStream(); + errorThread = new StreamCopyThread(upErr, msg.getRawStream()); + errorThread.start(); + + init(channel.getInputStream(), outputStream(channel)); } catch (TransportException err) { close(); @@ -258,6 +264,16 @@ public class TransportGitSsh extends SshTransport implements PackTransport { @Override public void close() { + if (errorThread != null) { + try { + errorThread.join(); + } catch (InterruptedException e) { + // Stop waiting and return anyway. + } finally { + errorThread = null; + } + } + super.close(); if (channel != null) { @@ -275,6 +291,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport { class SshPushConnection extends BasePackPushConnection { private ChannelExec channel; + private Thread errorThread; + private int exitStatus; SshPushConnection() throws TransportException { @@ -282,12 +300,16 @@ public class TransportGitSsh extends SshTransport implements PackTransport { try { final MessageWriter msg = new MessageWriter(); setMessageWriter(msg); - channel = exec(getOptionReceivePack(), msg.getRawStream()); - if (channel.isConnected()) - init(channel.getInputStream(), outputStream(channel)); - else - throw new TransportException(uri, getMessages()); + channel = exec(getOptionReceivePack()); + if (!channel.isConnected()) + throw new TransportException(uri, "connection failed"); + + final InputStream rpErr = channel.getErrStream(); + errorThread = new StreamCopyThread(rpErr, msg.getRawStream()); + errorThread.start(); + + init(channel.getInputStream(), outputStream(channel)); } catch (TransportException err) { close(); @@ -309,6 +331,16 @@ public class TransportGitSsh extends SshTransport implements PackTransport { @Override public void close() { + if (errorThread != null) { + try { + errorThread.join(); + } catch (InterruptedException e) { + // Stop waiting and return anyway. + } finally { + errorThread = null; + } + } + super.close(); if (channel != null) {