/*
- * 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>
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();
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);
}
}
+ 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.
class SshFetchConnection extends BasePackFetchConnection {
private ChannelExec channel;
+ private int exitStatus;
+
SshFetchConnection() throws TransportException {
super(TransportGitSsh.this);
try {
try {
readAdvertisedRefs();
} catch (NoRemoteRepositoryException notFound) {
+ close();
+ checkExecFailure(exitStatus, getOptionUploadPack());
throw cleanNotFound(notFound);
}
}
if (channel != null) {
try {
+ exitStatus = channel.getExitStatus();
if (channel.isConnected())
channel.disconnect();
} finally {
class SshPushConnection extends BasePackPushConnection {
private ChannelExec channel;
+ private int exitStatus;
+
SshPushConnection() throws TransportException {
super(TransportGitSsh.this);
try {
try {
readAdvertisedRefs();
} catch (NoRemoteRepositoryException notFound) {
+ close();
+ checkExecFailure(exitStatus, getOptionReceivePack());
throw cleanNotFound(notFound);
}
}
if (channel != null) {
try {
+ exitStatus = channel.getExitStatus();
if (channel.isConnected())
channel.disconnect();
} finally {