Skip to content
Snippets Groups Projects
Commit 08a77c04 authored by Shawn Pearce's avatar Shawn Pearce
Browse files

Check for remote server exec failures and report


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: default avatarShawn O. Pearce <spearce@spearce.org>
parent 0238a21b
No related branches found
No related tags found
No related merge requests found
/*
* 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 {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment