]> source.dussan.org Git - jgit.git/commitdiff
Check for remote server exec failures and report 40/240/1
authorShawn O. Pearce <spearce@spearce.org>
Sat, 23 Jan 2010 21:11:58 +0000 (13:11 -0800)
committerShawn O. Pearce <spearce@spearce.org>
Sat, 23 Jan 2010 21:11:58 +0000 (13:11 -0800)
If remote.name.uploadpack or .receivepack is misconfigured and points
to a non-existent command on the remote system, we should receive back
exit status 127.  Report this case specially with the command we used
so the user knows what is going.

Bug: 293703
Change-Id: I7504e7b6238d5d8e698d37db7411c4817a039d08
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java

index 55636f8dccbc69bdd31681e822265b762c15f1fe..5ee7887f6aefd6afcc5bce41e18c128625ffb992 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2009, Google Inc.
+ * Copyright (C) 2008-2010, Google Inc.
  * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
@@ -127,6 +127,23 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
                        cmd.append(QuotedString.BOURNE.quote(val));
        }
 
+       private String commandFor(final String exe) {
+               String path = uri.getPath();
+               if (uri.getScheme() != null && uri.getPath().startsWith("/~"))
+                       path = (uri.getPath().substring(1));
+
+               final StringBuilder cmd = new StringBuilder();
+               final int gitspace = exe.indexOf("git ");
+               if (gitspace >= 0) {
+                       sqMinimal(cmd, exe.substring(0, gitspace + 3));
+                       cmd.append(' ');
+                       sqMinimal(cmd, exe.substring(gitspace + 4));
+               } else
+                       sqMinimal(cmd, exe);
+               cmd.append(' ');
+               sqAlways(cmd, path);
+               return cmd.toString();
+       }
 
        ChannelExec exec(final String exe) throws TransportException {
                initSession();
@@ -134,21 +151,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
                final int tms = getTimeout() > 0 ? getTimeout() * 1000 : 0;
                try {
                        final ChannelExec channel = (ChannelExec) sock.openChannel("exec");
-                       String path = uri.getPath();
-                       if (uri.getScheme() != null && uri.getPath().startsWith("/~"))
-                               path = (uri.getPath().substring(1));
-
-                       final StringBuilder cmd = new StringBuilder();
-                       final int gitspace = exe.indexOf("git ");
-                       if (gitspace >= 0) {
-                               sqMinimal(cmd, exe.substring(0, gitspace + 3));
-                               cmd.append(' ');
-                               sqMinimal(cmd, exe.substring(gitspace + 4));
-                       } else
-                               sqMinimal(cmd, exe);
-                       cmd.append(' ');
-                       sqAlways(cmd, path);
-                       channel.setCommand(cmd.toString());
+                       channel.setCommand(commandFor(exe));
                        errStream = createErrorStream();
                        channel.setErrStream(errStream, true);
                        channel.connect(tms);
@@ -158,6 +161,17 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
                }
        }
 
+       void checkExecFailure(int status, String exe) throws TransportException {
+               if (status == 127) {
+                       String why = errStream.toString();
+                       IOException cause = null;
+                       if (why != null && why.length() > 0)
+                               cause = new IOException(why);
+                       throw new TransportException(uri, "cannot execute: "
+                                       + commandFor(exe), cause);
+               }
+       }
+
        /**
         * @return the error stream for the channel, the stream is used to detect
         *         specific error reasons for exceptions.
@@ -305,6 +319,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
        class SshFetchConnection extends BasePackFetchConnection {
                private ChannelExec channel;
 
+               private int exitStatus;
+
                SshFetchConnection() throws TransportException {
                        super(TransportGitSsh.this);
                        try {
@@ -327,6 +343,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
                        try {
                                readAdvertisedRefs();
                        } catch (NoRemoteRepositoryException notFound) {
+                               close();
+                               checkExecFailure(exitStatus, getOptionUploadPack());
                                throw cleanNotFound(notFound);
                        }
                }
@@ -337,6 +355,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
 
                        if (channel != null) {
                                try {
+                                       exitStatus = channel.getExitStatus();
                                        if (channel.isConnected())
                                                channel.disconnect();
                                } finally {
@@ -349,6 +368,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
        class SshPushConnection extends BasePackPushConnection {
                private ChannelExec channel;
 
+               private int exitStatus;
+
                SshPushConnection() throws TransportException {
                        super(TransportGitSsh.this);
                        try {
@@ -371,6 +392,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
                        try {
                                readAdvertisedRefs();
                        } catch (NoRemoteRepositoryException notFound) {
+                               close();
+                               checkExecFailure(exitStatus, getOptionReceivePack());
                                throw cleanNotFound(notFound);
                        }
                }
@@ -381,6 +404,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
 
                        if (channel != null) {
                                try {
+                                       exitStatus = channel.getExitStatus();
                                        if (channel.isConnected())
                                                channel.disconnect();
                                } finally {