Merge "Check for remote server exec failures and report"

This commit is contained in:
Shawn Pearce 2010-01-29 13:45:17 -05:00 committed by Code Review
commit 79bb1594b4
1 changed files with 40 additions and 16 deletions

View 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 @@ private static void sq(final StringBuilder cmd, final String val) {
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 @@ ChannelExec exec(final String exe) throws TransportException {
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 @@ ChannelExec exec(final String exe) throws TransportException {
}
}
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 void run() {
class SshFetchConnection extends BasePackFetchConnection {
private ChannelExec channel;
private int exitStatus;
SshFetchConnection() throws TransportException {
super(TransportGitSsh.this);
try {
@ -327,6 +343,8 @@ class SshFetchConnection extends BasePackFetchConnection {
try {
readAdvertisedRefs();
} catch (NoRemoteRepositoryException notFound) {
close();
checkExecFailure(exitStatus, getOptionUploadPack());
throw cleanNotFound(notFound);
}
}
@ -337,6 +355,7 @@ public void close() {
if (channel != null) {
try {
exitStatus = channel.getExitStatus();
if (channel.isConnected())
channel.disconnect();
} finally {
@ -349,6 +368,8 @@ public void close() {
class SshPushConnection extends BasePackPushConnection {
private ChannelExec channel;
private int exitStatus;
SshPushConnection() throws TransportException {
super(TransportGitSsh.this);
try {
@ -371,6 +392,8 @@ class SshPushConnection extends BasePackPushConnection {
try {
readAdvertisedRefs();
} catch (NoRemoteRepositoryException notFound) {
close();
checkExecFailure(exitStatus, getOptionReceivePack());
throw cleanNotFound(notFound);
}
}
@ -381,6 +404,7 @@ public void close() {
if (channel != null) {
try {
exitStatus = channel.getExitStatus();
if (channel.isConnected())
channel.disconnect();
} finally {