mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-02 22:55:26 +02:00
Bug 530750 - Enable launch support using proxy. Also adds support for
command shell and fixes a number of bugs. Change-Id: I6b9a0bf40647d6f5682c425c754371f8af6cb918 Signed-off-by: Greg Watson <g.watson@computer.org>
This commit is contained in:
parent
a0fe3f1cf2
commit
ea50b5d22c
45 changed files with 703 additions and 344 deletions
|
@ -40,7 +40,7 @@
|
|||
</connectionService>
|
||||
<connectionService
|
||||
connectionTypeId="org.eclipse.remote.Proxy"
|
||||
factory="org.eclipse.remote.internal.proxy.core.ProxyCommandShellService$Factory"
|
||||
factory="org.eclipse.remote.internal.proxy.core.ProxyConnection$Factory"
|
||||
service="org.eclipse.remote.core.IRemoteCommandShellService">
|
||||
</connectionService>
|
||||
<processService
|
||||
|
@ -58,6 +58,11 @@
|
|||
factory="org.eclipse.remote.internal.proxy.core.ProxyProcess$Factory"
|
||||
service="org.eclipse.remote.core.IRemoteProcessTerminalService">
|
||||
</processService>
|
||||
<processService
|
||||
connectionTypeId="org.eclipse.remote.Proxy"
|
||||
factory="org.eclipse.remote.internal.proxy.core.ProxyProcess$Factory"
|
||||
service="org.eclipse.remote.internal.proxy.core.ProxyProcess">
|
||||
</processService>
|
||||
</extension>
|
||||
<extension
|
||||
id="org.eclipse.remote.proxy.filesystem"
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.core;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.remote.core.IRemoteCommandShellService;
|
||||
import org.eclipse.remote.core.IRemoteConnection;
|
||||
import org.eclipse.remote.core.IRemoteProcess;
|
||||
|
||||
public class ProxyCommandShellService implements IRemoteCommandShellService {
|
||||
private IRemoteConnection fRemoteConnection;
|
||||
|
||||
public ProxyCommandShellService(IRemoteConnection remoteConnection) {
|
||||
fRemoteConnection = remoteConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRemoteConnection getRemoteConnection() {
|
||||
return fRemoteConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRemoteProcess getCommandShell(int flags) throws IOException {
|
||||
return null;
|
||||
// return new JSchProcessBuilder(getRemoteConnection()).start(flags);
|
||||
}
|
||||
|
||||
public static class Factory implements IRemoteConnection.Service.Factory {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.remote.core.IRemoteConnection.Service.Factory#getService(org.eclipse.remote.core.IRemoteConnection,
|
||||
* java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends IRemoteConnection.Service> T getService(IRemoteConnection connection, Class<T> service) {
|
||||
if (IRemoteCommandShellService.class.equals(service)) {
|
||||
return (T) new ProxyCommandShellService(connection);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,8 +37,8 @@ import org.eclipse.remote.internal.proxy.core.commands.GetCwdCommand;
|
|||
import org.eclipse.remote.internal.proxy.core.commands.GetEnvCommand;
|
||||
import org.eclipse.remote.internal.proxy.core.commands.GetPropertiesCommand;
|
||||
import org.eclipse.remote.internal.proxy.core.messages.Messages;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannelManager;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannelManager;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
||||
import com.jcraft.jsch.ChannelShell;
|
||||
|
@ -48,7 +48,8 @@ import com.jcraft.jsch.ChannelShell;
|
|||
*/
|
||||
public class ProxyConnection implements IRemoteConnectionControlService,
|
||||
IRemoteConnectionChangeListener, IRemoteProcessService,
|
||||
IRemoteCommandShellService, IRemoteConnectionHostService {
|
||||
IRemoteCommandShellService, IRemoteConnectionHostService,
|
||||
IRemoteConnectionPropertyService {
|
||||
// Connection Type ID
|
||||
public static final String JSCH_ID = "org.eclipse.remote.Proxy"; //$NON-NLS-1$
|
||||
|
||||
|
@ -72,7 +73,6 @@ public class ProxyConnection implements IRemoteConnectionControlService,
|
|||
private StreamChannelManager channelMux;
|
||||
private StreamChannel commandChannel;
|
||||
private boolean isOpen;
|
||||
private boolean proxyRunning;
|
||||
|
||||
private final IRemoteConnection fRemoteConnection;
|
||||
|
||||
|
@ -133,7 +133,8 @@ public class ProxyConnection implements IRemoteConnectionControlService,
|
|||
|| IRemoteConnectionPropertyService.class.equals(service)
|
||||
|| IRemoteConnectionHostService.class.equals(service)
|
||||
|| IRemoteProcessService.class.equals(service)
|
||||
|| IRemoteCommandShellService.class.equals(service)) {
|
||||
|| IRemoteCommandShellService.class.equals(service)
|
||||
|| IRemoteConnectionPropertyService.class.equals(service)) {
|
||||
return (T) connection.getService(ProxyConnection.class);
|
||||
} else {
|
||||
return null;
|
||||
|
@ -348,7 +349,7 @@ public class ProxyConnection implements IRemoteConnectionControlService,
|
|||
|
||||
@Override
|
||||
public IRemoteProcess getCommandShell(int flags) throws IOException {
|
||||
throw new IOException("Not implemented yet");
|
||||
return new ProxyProcessBuilder(this).start(flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -454,4 +455,9 @@ public class ProxyConnection implements IRemoteConnectionControlService,
|
|||
wc.setAttribute(USERNAME_ATTR, username);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String key) {
|
||||
return fProperties.get(key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ public class ProxyConnectionBootstrap {
|
|||
int n;
|
||||
while ((n = in.read(buf)) >= 0) {
|
||||
if (n < 510) {
|
||||
writer.write(encoder.encodeToString(Arrays.copyOf(buf, n)) + "\n");
|
||||
writer.write(encoder.encodeToString(Arrays.copyOf(buf, n)) + "\n"); //$NON-NLS-1$
|
||||
} else {
|
||||
writer.write(encoder.encodeToString(buf));
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ public class ProxyConnectionBootstrap {
|
|||
throw new RemoteConnectionException(Messages.ProxyConnectionBootstrap_8);
|
||||
}
|
||||
exec = (ChannelExec) session.openChannel("exec"); //$NON-NLS-1$
|
||||
exec.setCommand("/bin/sh -l"); //$NON-NLS-1$
|
||||
exec.setCommand("/bin/bash -l"); //$NON-NLS-1$
|
||||
exec.connect();
|
||||
return exec;
|
||||
} catch (JSchException e) {
|
||||
|
|
|
@ -12,18 +12,18 @@ import java.io.DataOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.remote.core.IRemoteConnection;
|
||||
import org.eclipse.remote.core.IRemoteProcess;
|
||||
import org.eclipse.remote.core.IRemoteProcessBuilder;
|
||||
import org.eclipse.remote.core.IRemoteProcessControlService;
|
||||
import org.eclipse.remote.core.IRemoteProcessSignalService;
|
||||
import org.eclipse.remote.core.IRemoteProcessTerminalService;
|
||||
import org.eclipse.remote.internal.core.RemoteProcess;
|
||||
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
|
||||
public class ProxyProcess extends RemoteProcess implements IRemoteProcessControlService, IRemoteProcessTerminalService {
|
||||
public class ProxyProcess implements IRemoteProcessControlService, IRemoteProcessTerminalService {
|
||||
private IRemoteProcess remoteProcess;
|
||||
|
||||
private final StreamChannel stdIOChan;
|
||||
private final StreamChannel stdErrChan;
|
||||
private final StreamChannel controlChan;
|
||||
|
@ -44,8 +44,8 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IRemoteProcess.Service> T getService(IRemoteProcess remoteProcess, Class<T> service) {
|
||||
if (ProxyProcess.class.equals(service) && remoteProcess instanceof ProxyProcess) {
|
||||
return (T) remoteProcess;
|
||||
if (ProxyProcess.class.equals(service)) {
|
||||
return (T) new ProxyProcess(remoteProcess);
|
||||
}
|
||||
if (IRemoteProcessControlService.class.equals(service) || IRemoteProcessSignalService.class.equals(service)
|
||||
|| IRemoteProcessTerminalService.class.equals(service)) {
|
||||
|
@ -55,17 +55,19 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
|||
}
|
||||
}
|
||||
|
||||
public ProxyProcess(IRemoteConnection connection, IRemoteProcessBuilder builder, StreamChannel stdIO, StreamChannel stdErr, StreamChannel control) {
|
||||
super(connection, builder);
|
||||
stdIOChan = stdIO;
|
||||
stdErrChan = stdErr;
|
||||
controlChan = control;
|
||||
cmdStream = new DataOutputStream(control.getOutputStream());
|
||||
resultStream = new DataInputStream(control.getInputStream());
|
||||
protected ProxyProcess(IRemoteProcess process) {
|
||||
remoteProcess = process;
|
||||
ProxyProcessBuilder builder = (ProxyProcessBuilder)process.getProcessBuilder();
|
||||
List<StreamChannel> streams = builder.getStreams();
|
||||
controlChan = streams.get(0);
|
||||
stdIOChan = streams.get(1);
|
||||
stdErrChan = streams.size() > 2 ? streams.get(2) : null;
|
||||
cmdStream = new DataOutputStream(controlChan.getOutputStream());
|
||||
resultStream = new DataInputStream(controlChan.getInputStream());
|
||||
isCompleted = false;
|
||||
exitValue = 0;
|
||||
|
||||
cmdThread = new Thread("process " + builder.command().get(0) + " result reader") { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
cmdThread = new Thread("process result reader") { //$NON-NLS-1$
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
@ -77,36 +79,15 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
|||
try {
|
||||
stdIOChan.close();
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
// Ignore
|
||||
}
|
||||
try {
|
||||
stdErrChan.close();
|
||||
if (stdErrChan != null) {
|
||||
stdErrChan.close();
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
// Ignore
|
||||
}
|
||||
// if (stdout == null) {
|
||||
// try {
|
||||
// stdIOChan.getInputStream().close();
|
||||
// } catch (IOException e) {
|
||||
// // Ignore
|
||||
// }
|
||||
// }
|
||||
// if (stdin == null) {
|
||||
// try {
|
||||
// stdIOChan.getOutputStream().close();
|
||||
// } catch (IOException e) {
|
||||
// // Ignore
|
||||
// }
|
||||
// }
|
||||
// if (stderr == null) {
|
||||
// try {
|
||||
// stdErrChan.close();
|
||||
// } catch (IOException e) {
|
||||
// // Ignore
|
||||
// }
|
||||
// }
|
||||
try {
|
||||
controlChan.close();
|
||||
} catch (IOException e) {
|
||||
|
@ -125,7 +106,7 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
|||
@Override
|
||||
public void destroy() {
|
||||
try {
|
||||
cmdStream.writeByte(0);
|
||||
cmdStream.writeByte(Protocol.CONTROL_KILL);
|
||||
cmdStream.flush();
|
||||
} catch (IOException e) {
|
||||
isCompleted = true;
|
||||
|
@ -152,6 +133,19 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
|||
*/
|
||||
@Override
|
||||
public InputStream getErrorStream() {
|
||||
if (stdErrChan == null) {
|
||||
return new InputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
return stdErrChan.getInputStream();
|
||||
}
|
||||
|
||||
|
@ -203,6 +197,15 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
|||
|
||||
@Override
|
||||
public void setTerminalSize(int cols, int rows, int pwidth, int pheight) {
|
||||
// Nothing?
|
||||
try {
|
||||
cmdStream.writeByte(Protocol.CONTROL_SETTERMINALSIZE);
|
||||
cmdStream.writeInt(cols);
|
||||
cmdStream.writeInt(rows);
|
||||
cmdStream.writeInt(pwidth);
|
||||
cmdStream.writeInt(pheight);
|
||||
cmdStream.flush();
|
||||
} catch (IOException e) {
|
||||
// Dealt with somewhere else hopefully
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
package org.eclipse.remote.internal.proxy.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -22,6 +23,7 @@ import org.eclipse.remote.core.IRemoteFileService;
|
|||
import org.eclipse.remote.core.IRemoteProcess;
|
||||
import org.eclipse.remote.core.IRemoteProcessBuilder;
|
||||
import org.eclipse.remote.internal.proxy.core.commands.ExecCommand;
|
||||
import org.eclipse.remote.internal.proxy.core.commands.ShellCommand;
|
||||
import org.eclipse.remote.internal.proxy.core.messages.Messages;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
@ -29,6 +31,7 @@ import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
|||
public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
||||
private final ProxyConnection proxyConnection;
|
||||
private Map<String, String> remoteEnv;
|
||||
private List<StreamChannel> streams = new ArrayList<>();
|
||||
|
||||
public ProxyProcessBuilder(ProxyConnection connection, List<String> command) {
|
||||
super(connection.getRemoteConnection(), command);
|
||||
|
@ -42,6 +45,17 @@ public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
|||
public ProxyProcessBuilder(ProxyConnection connection, String... command) {
|
||||
this(connection, Arrays.asList(command));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for creating command shell
|
||||
* @param connection
|
||||
*/
|
||||
public ProxyProcessBuilder(ProxyConnection connection) {
|
||||
super(connection.getRemoteConnection(), (List<String>)null);
|
||||
proxyConnection = connection;
|
||||
redirectErrorStream(true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
@ -76,41 +90,66 @@ public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
|||
*/
|
||||
@Override
|
||||
public IRemoteProcess start(int flags) throws IOException {
|
||||
final List<String> cmdArgs = command();
|
||||
if (cmdArgs.size() < 1) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
/*
|
||||
* If environment has not been touched, then don't send anything
|
||||
*/
|
||||
final Map<String, String> env = new HashMap<String, String>();
|
||||
if (remoteEnv != null) {
|
||||
env.putAll(remoteEnv);
|
||||
}
|
||||
final boolean append = (flags & IRemoteProcessBuilder.APPEND_ENVIRONMENT) != 0 || remoteEnv == null;
|
||||
|
||||
final ProxyConnection conn = getRemoteConnection().getService(ProxyConnection.class);
|
||||
if (conn == null) {
|
||||
throw new IOException(Messages.ProxyProcessBuilder_0);
|
||||
}
|
||||
|
||||
final StreamChannel chanStdIO = conn.openChannel();
|
||||
final StreamChannel chanStdErr = conn.openChannel();
|
||||
final StreamChannel chanControl = conn.openChannel();
|
||||
Job job;
|
||||
|
||||
Job job = new Job("process executor") { //$NON-NLS-1$
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
ExecCommand cmd = new ExecCommand(conn, cmdArgs, env, directory().toURI().getPath(), redirectErrorStream(), append,
|
||||
chanStdIO.getId(), chanStdErr.getId(), chanControl.getId());
|
||||
try {
|
||||
cmd.getResult(monitor);
|
||||
} catch (ProxyException e) {
|
||||
return new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage());
|
||||
}
|
||||
return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
|
||||
final List<String> cmdArgs = command();
|
||||
if (cmdArgs != null) {
|
||||
if (cmdArgs.size() < 1) {
|
||||
throw new IOException(Messages.ProxyProcessBuilder_1);
|
||||
}
|
||||
};
|
||||
/*
|
||||
* If environment has not been touched, then don't send anything
|
||||
*/
|
||||
final Map<String, String> env = new HashMap<String, String>();
|
||||
if (remoteEnv != null) {
|
||||
env.putAll(remoteEnv);
|
||||
}
|
||||
|
||||
final boolean append = (flags & IRemoteProcessBuilder.APPEND_ENVIRONMENT) != 0 || remoteEnv == null;
|
||||
|
||||
streams.add(conn.openChannel());
|
||||
streams.add(conn.openChannel());
|
||||
streams.add(conn.openChannel());
|
||||
|
||||
job = new Job("process executor") { //$NON-NLS-1$
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
ExecCommand cmd = new ExecCommand(conn, cmdArgs, env, directory().toURI().getPath(), redirectErrorStream(), append,
|
||||
streams.get(0).getId(), streams.get(1).getId(), streams.get(2).getId());
|
||||
try {
|
||||
cmd.getResult(monitor);
|
||||
} catch (ProxyException e) {
|
||||
return new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage());
|
||||
}
|
||||
return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
/*
|
||||
* Start command shell
|
||||
*/
|
||||
streams.add(conn.openChannel());
|
||||
streams.add(conn.openChannel());
|
||||
|
||||
job = new Job("process executor") { //$NON-NLS-1$
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
ShellCommand cmd = new ShellCommand(conn, streams.get(0).getId(), streams.get(1).getId());
|
||||
try {
|
||||
cmd.getResult(monitor);
|
||||
} catch (ProxyException e) {
|
||||
return new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage());
|
||||
}
|
||||
return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
job.schedule();
|
||||
try {
|
||||
job.join();
|
||||
|
@ -121,7 +160,10 @@ public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
|||
throw new IOException(job.getResult().getMessage());
|
||||
}
|
||||
|
||||
ProxyProcess proc = new ProxyProcess(getRemoteConnection(), this, chanStdIO, chanStdErr, chanControl);
|
||||
return proc;
|
||||
return newRemoteProcess();
|
||||
}
|
||||
|
||||
public List<StreamChannel> getStreams() {
|
||||
return streams;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.concurrent.TimeoutException;
|
|||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.SubMonitor;
|
||||
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
||||
import org.eclipse.remote.internal.proxy.core.messages.Messages;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
||||
|
@ -28,15 +29,11 @@ public abstract class AbstractCommand<T> implements Callable<T> {
|
|||
private static ExecutorService executors = Executors.newSingleThreadExecutor();
|
||||
|
||||
private final ProxyConnection connection;
|
||||
|
||||
|
||||
private Future<T> asyncCmdInThread() throws ProxyException {
|
||||
return executors.submit(this);
|
||||
}
|
||||
|
||||
private void finalizeCmdInThread() {
|
||||
}
|
||||
|
||||
public StreamChannel openChannel() throws IOException {
|
||||
return connection.openChannel();
|
||||
}
|
||||
|
@ -52,12 +49,8 @@ public abstract class AbstractCommand<T> implements Callable<T> {
|
|||
public T getResult(IProgressMonitor monitor) throws ProxyException {
|
||||
Future<T> future = null;
|
||||
progressMonitor = SubMonitor.convert(monitor, 10);
|
||||
try {
|
||||
future = asyncCmdInThread();
|
||||
return waitCmdInThread(future);
|
||||
} finally {
|
||||
finalizeCmdInThread();
|
||||
}
|
||||
future = asyncCmdInThread();
|
||||
return waitCmdInThread(future);
|
||||
}
|
||||
|
||||
private T waitCmdInThread(Future<T> future) throws ProxyException {
|
||||
|
@ -78,7 +71,7 @@ public abstract class AbstractCommand<T> implements Callable<T> {
|
|||
Thread.currentThread().interrupt(); // set current thread flag
|
||||
}
|
||||
future.cancel(true);
|
||||
throw new ProxyException("Operation cancelled by user");
|
||||
throw new ProxyException(Messages.AbstractCommand_0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,7 +44,6 @@ public class ChildInfosCommand extends AbstractCommand<IFileInfo[]> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("childinfos command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ public class DeleteCommand extends AbstractCommand<Void> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("delete command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -26,12 +26,12 @@ public class ExecCommand extends AbstractCommand<Void> {
|
|||
private final String directory;
|
||||
private final boolean appendEnv;
|
||||
private final boolean redirect;
|
||||
private final int chanA;
|
||||
private final int chanB;
|
||||
private final int chanC;
|
||||
private final int cmdChan;
|
||||
private final int ioChan;
|
||||
private final int errChan;
|
||||
|
||||
public ExecCommand(ProxyConnection conn, List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv,
|
||||
int chanA, int chanB, int chanC) {
|
||||
int cmdChan, int ioChan, int errChan) {
|
||||
super(conn);
|
||||
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
|
||||
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
|
||||
|
@ -40,18 +40,18 @@ public class ExecCommand extends AbstractCommand<Void> {
|
|||
this.directory = directory;
|
||||
this.redirect = redirect;
|
||||
this.appendEnv = appendEnv;
|
||||
this.chanA = chanA;
|
||||
this.chanB = chanB;
|
||||
this.chanC = chanC;
|
||||
this.cmdChan = cmdChan;
|
||||
this.ioChan = ioChan;
|
||||
this.errChan = errChan;
|
||||
}
|
||||
|
||||
public Void call() throws ProxyException {
|
||||
try {
|
||||
out.writeByte(Protocol.PROTO_COMMAND);
|
||||
out.writeShort(Protocol.CMD_EXEC);
|
||||
out.writeByte(chanA);
|
||||
out.writeByte(chanB);
|
||||
out.writeByte(chanC);
|
||||
out.writeByte(cmdChan);
|
||||
out.writeByte(ioChan);
|
||||
out.writeByte(errChan);
|
||||
out.writeInt(command.size());
|
||||
for (String arg : command) {
|
||||
out.writeUTF(arg);
|
||||
|
@ -69,7 +69,6 @@ public class ExecCommand extends AbstractCommand<Void> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("exec command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -44,7 +44,6 @@ public class FetchInfoCommand extends AbstractCommand<IFileInfo> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("fetchinfo command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ public class GetCwdCommand extends AbstractCommand<String> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("getcwd command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ public class GetEnvCommand extends AbstractCommand<Map<String, String>> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("getenv command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
||||
public class GetInputStreamCommand extends AbstractCommand<InputStream> {
|
||||
|
@ -47,7 +47,6 @@ public class GetInputStreamCommand extends AbstractCommand<InputStream> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("getinputstream command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.io.IOException;
|
|||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
||||
public class GetOutputStreamCommand extends AbstractCommand<OutputStream> {
|
||||
|
@ -47,7 +47,6 @@ public class GetOutputStreamCommand extends AbstractCommand<OutputStream> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("getoutputstream command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ public class GetPropertiesCommand extends AbstractCommand<Map<String, String>> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("getproperties command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ public class MkdirCommand extends AbstractCommand<Void> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("mkdir command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -47,7 +47,6 @@ public class PutInfoCommand extends AbstractCommand<Void> {
|
|||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
System.err.println("fetchinfo command failed:" + errMsg);
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Oak Ridge National Laboratory and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.core.commands;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
||||
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
||||
public class ShellCommand extends AbstractCommand<Void> {
|
||||
|
||||
private final DataOutputStream out;
|
||||
private final DataInputStream in;
|
||||
private final int cmdChan;
|
||||
private final int ioChan;
|
||||
|
||||
public ShellCommand(ProxyConnection conn, int cmdChan, int ioChan) {
|
||||
super(conn);
|
||||
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
|
||||
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
|
||||
this.cmdChan = cmdChan;
|
||||
this.ioChan = ioChan;
|
||||
}
|
||||
|
||||
public Void call() throws ProxyException {
|
||||
try {
|
||||
out.writeByte(Protocol.PROTO_COMMAND);
|
||||
out.writeShort(Protocol.CMD_SHELL);
|
||||
out.writeByte(cmdChan);
|
||||
out.writeByte(ioChan);
|
||||
out.flush();
|
||||
|
||||
byte res = in.readByte();
|
||||
if (res != Protocol.PROTO_OK) {
|
||||
String errMsg = in.readUTF();
|
||||
throw new ProxyException(errMsg);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ProxyException(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,8 @@ import org.eclipse.osgi.util.NLS;
|
|||
public class Messages extends NLS {
|
||||
private static final String BUNDLE_ID = "org.eclipse.remote.internal.proxy.core.messages.messages"; //$NON-NLS-1$
|
||||
|
||||
public static String AbstractCommand_0;
|
||||
|
||||
public static String AbstractRemoteCommand_format1;
|
||||
public static String AbstractRemoteCommand_format2;
|
||||
public static String AbstractRemoteCommand_Get_symlink_target;
|
||||
|
@ -56,6 +58,8 @@ public class Messages extends NLS {
|
|||
public static String JschFileStore_A_file_of_name_already_exists;
|
||||
public static String JschFileStore_The_parent_of_directory_does_not_exist;
|
||||
|
||||
public static String ProxyCommandShell_0;
|
||||
|
||||
public static String ProxyConnection_0;
|
||||
|
||||
public static String ProxyConnection_2;
|
||||
|
@ -98,6 +102,8 @@ public class Messages extends NLS {
|
|||
|
||||
public static String ProxyProcessBuilder_0;
|
||||
|
||||
public static String ProxyProcessBuilder_1;
|
||||
|
||||
static {
|
||||
// load message values from bundle file
|
||||
NLS.initializeMessages(BUNDLE_ID, Messages.class);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
# Contributors:
|
||||
# IBM Corporation - initial implementation
|
||||
###############################################################################
|
||||
AbstractCommand_0=Operation cancelled by user
|
||||
AbstractRemoteCommand_format1={0,number,integer} {1} completed
|
||||
AbstractRemoteCommand_format2={0,number,integer} {1} of {2,number,integer} {3} complete ({4,number,percent})
|
||||
AbstractRemoteCommand_Get_symlink_target=Get symlink target
|
||||
|
@ -43,6 +44,7 @@ JschFileStore_No_remote_services_found_for_URI=No remote services found for URI:
|
|||
JschFileStore_The_directory_could_not_be_created=The directory {0} could not be created
|
||||
JschFileStore_A_file_of_name_already_exists=A file of name {0} already exists
|
||||
JschFileStore_The_parent_of_directory_does_not_exist=The parent of directory {0} does not exist
|
||||
ProxyCommandShell_0=Unable to locate connection for command shell
|
||||
ProxyConnection_0=Opening connection...
|
||||
ProxyConnection_2=User canceled opening connection
|
||||
ProxyConnectionBootstrap_0=Initializing
|
||||
|
@ -64,3 +66,4 @@ ProxyFileStore_5=A file of name {0} already exists
|
|||
ProxyFileStore_6=File {0} does not exist
|
||||
ProxyFileStore_7={0} is a directory
|
||||
ProxyProcessBuilder_0=Unable to located connection for this process
|
||||
ProxyProcessBuilder_1=No command to run\!
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.remote.proxy.protocol.core;singleton:=true
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Version: 2.0.0.qualifier
|
||||
Bundle-Activator: org.eclipse.remote.internal.proxy.protocol.core.Activator
|
||||
Bundle-Vendor: %pluginProvider
|
||||
Bundle-ActivationPolicy: lazy
|
||||
|
|
|
@ -12,5 +12,5 @@
|
|||
|
||||
<artifactId>org.eclipse.remote.proxy.protocol.core</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</project>
|
||||
|
|
|
@ -17,16 +17,25 @@ public class Protocol {
|
|||
|
||||
public final static short CmdBase = 100;
|
||||
|
||||
public final static short CMD_EXEC = CmdBase + 1;
|
||||
public final static short CMD_SHELL = CmdBase + 2;
|
||||
public final static short CMD_GETCWD = CmdBase + 3;
|
||||
public final static short CMD_GETENV = CmdBase + 4;
|
||||
public final static short CMD_CHILDINFOS = CmdBase + 5;
|
||||
public final static short CMD_DELETE = CmdBase + 6;
|
||||
public final static short CMD_FETCHINFO = CmdBase + 7;
|
||||
public final static short CMD_GETINPUTSTREAM = CmdBase + 8;
|
||||
public final static short CMD_EXEC = CmdBase + 1;
|
||||
public final static short CMD_SHELL = CmdBase + 2;
|
||||
public final static short CMD_GETCWD = CmdBase + 3;
|
||||
public final static short CMD_GETENV = CmdBase + 4;
|
||||
public final static short CMD_CHILDINFOS = CmdBase + 5;
|
||||
public final static short CMD_DELETE = CmdBase + 6;
|
||||
public final static short CMD_FETCHINFO = CmdBase + 7;
|
||||
public final static short CMD_GETINPUTSTREAM = CmdBase + 8;
|
||||
public final static short CMD_GETOUTPUTSTREAM = CmdBase + 9;
|
||||
public final static short CMD_MKDIR = CmdBase + 10;
|
||||
public final static short CMD_MKDIR = CmdBase + 10;
|
||||
public final static short CMD_PUTINFO = CmdBase + 11;
|
||||
public final static short CMD_GETPROPERTIES = CmdBase + 12;
|
||||
public final static short CMD_GETPROPERTIES = CmdBase + 12;
|
||||
|
||||
/**
|
||||
* @since 2.0
|
||||
*/
|
||||
public final static byte CONTROL_KILL = 0;
|
||||
/**
|
||||
* @since 2.0
|
||||
*/
|
||||
public final static byte CONTROL_SETTERMINALSIZE = 1;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
eclipse.preferences.version=1
|
||||
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
|
||||
sp_cleanup.add_default_serial_version_id=true
|
||||
sp_cleanup.add_generated_serial_version_id=false
|
||||
sp_cleanup.add_missing_annotations=true
|
||||
sp_cleanup.add_missing_deprecated_annotations=true
|
||||
sp_cleanup.add_missing_methods=false
|
||||
sp_cleanup.add_missing_nls_tags=false
|
||||
sp_cleanup.add_missing_override_annotations=true
|
||||
sp_cleanup.add_missing_override_annotations_interface_methods=true
|
||||
sp_cleanup.add_serial_version_id=false
|
||||
sp_cleanup.always_use_blocks=true
|
||||
sp_cleanup.always_use_parentheses_in_expressions=false
|
||||
sp_cleanup.always_use_this_for_non_static_field_access=false
|
||||
sp_cleanup.always_use_this_for_non_static_method_access=false
|
||||
sp_cleanup.convert_functional_interfaces=false
|
||||
sp_cleanup.convert_to_enhanced_for_loop=false
|
||||
sp_cleanup.correct_indentation=false
|
||||
sp_cleanup.format_source_code=false
|
||||
sp_cleanup.format_source_code_changes_only=false
|
||||
sp_cleanup.insert_inferred_type_arguments=false
|
||||
sp_cleanup.make_local_variable_final=true
|
||||
sp_cleanup.make_parameters_final=false
|
||||
sp_cleanup.make_private_fields_final=true
|
||||
sp_cleanup.make_type_abstract_if_missing_method=false
|
||||
sp_cleanup.make_variable_declarations_final=false
|
||||
sp_cleanup.never_use_blocks=false
|
||||
sp_cleanup.never_use_parentheses_in_expressions=true
|
||||
sp_cleanup.on_save_use_additional_actions=false
|
||||
sp_cleanup.organize_imports=true
|
||||
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
|
||||
sp_cleanup.remove_private_constructors=true
|
||||
sp_cleanup.remove_redundant_type_arguments=false
|
||||
sp_cleanup.remove_trailing_whitespaces=false
|
||||
sp_cleanup.remove_trailing_whitespaces_all=true
|
||||
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
|
||||
sp_cleanup.remove_unnecessary_casts=true
|
||||
sp_cleanup.remove_unnecessary_nls_tags=false
|
||||
sp_cleanup.remove_unused_imports=false
|
||||
sp_cleanup.remove_unused_local_variables=false
|
||||
sp_cleanup.remove_unused_private_fields=true
|
||||
sp_cleanup.remove_unused_private_members=false
|
||||
sp_cleanup.remove_unused_private_methods=true
|
||||
sp_cleanup.remove_unused_private_types=true
|
||||
sp_cleanup.sort_members=false
|
||||
sp_cleanup.sort_members_all=false
|
||||
sp_cleanup.use_anonymous_class_creation=false
|
||||
sp_cleanup.use_blocks=false
|
||||
sp_cleanup.use_blocks_only_for_return_and_throw=false
|
||||
sp_cleanup.use_lambda=true
|
||||
sp_cleanup.use_parentheses_in_expressions=false
|
||||
sp_cleanup.use_this_for_non_static_field_access=false
|
||||
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
|
||||
sp_cleanup.use_this_for_non_static_method_access=false
|
||||
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
|
|
@ -15,3 +15,4 @@ Import-Package: org.eclipse.core.filesystem,
|
|||
org.osgi.framework.launch
|
||||
Bundle-Vendor: %pluginProvider
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: org.eclipse.cdt.core.native
|
||||
|
|
|
@ -25,7 +25,7 @@ public class Application implements IApplication {
|
|||
public Object start(IApplicationContext context) throws Exception {
|
||||
String[] args = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
|
||||
for (String arg : args) {
|
||||
if (arg.equals("-magic")) {
|
||||
if (arg.equals("-magic")) { //$NON-NLS-1$
|
||||
ByteBuffer b = ByteBuffer.allocate(4);
|
||||
b.putInt(Protocol.MAGIC);
|
||||
System.out.write(b.array());
|
||||
|
@ -40,5 +40,6 @@ public class Application implements IApplication {
|
|||
* @see org.eclipse.equinox.app.IApplication#stop()
|
||||
*/
|
||||
public void stop() {
|
||||
// Nothing
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,18 +16,19 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.remote.internal.proxy.server.commands.AbstractServerCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerChildInfosCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerDeleteCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerExecCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerFetchInfoCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetCwdCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetEnvCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetInputStreamCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetOutputStreamCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetPropertiesCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerMkdirCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.commands.ServerPutInfoCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.AbstractServerCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerChildInfosCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerDeleteCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerExecCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerFetchInfoCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetCwdCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetEnvCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetInputStreamCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetOutputStreamCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetPropertiesCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerMkdirCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerPutInfoCommand;
|
||||
import org.eclipse.remote.internal.proxy.server.core.commands.ServerShellCommand;
|
||||
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
||||
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
|
@ -48,7 +49,7 @@ public class CommandServer implements Runnable {
|
|||
}
|
||||
|
||||
public void run() {
|
||||
new Thread("cmd reader") {
|
||||
new Thread("cmd reader") { //$NON-NLS-1$
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
@ -117,6 +118,10 @@ public class CommandServer implements Runnable {
|
|||
serverCmd = cmdExec(in);
|
||||
break;
|
||||
|
||||
case Protocol.CMD_SHELL:
|
||||
serverCmd = cmdShell(in);
|
||||
break;
|
||||
|
||||
case Protocol.CMD_FETCHINFO:
|
||||
serverCmd = cmdFetchInfo(in);
|
||||
break;
|
||||
|
@ -151,16 +156,16 @@ public class CommandServer implements Runnable {
|
|||
|
||||
default:
|
||||
System.err.println("Invalid command ID: " + cmd);
|
||||
throw new ProxyException("Invalid command ID: " + cmd);
|
||||
throw new ProxyException("Invalid command ID: " + cmd); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
serverCmd.exec();
|
||||
}
|
||||
|
||||
private AbstractServerCommand cmdExec(DataInputStream in) throws ProxyException, IOException {
|
||||
int chanAId = in.readByte();
|
||||
int chanBId = in.readByte();
|
||||
int chanCId = in.readByte();
|
||||
int cmdChanId = in.readByte();
|
||||
int ioChanId = in.readByte();
|
||||
int errChanId = in.readByte();
|
||||
int length = in.readInt();
|
||||
List<String> command = new ArrayList<String>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
@ -176,25 +181,30 @@ public class CommandServer implements Runnable {
|
|||
String dir = in.readUTF();
|
||||
boolean redirect = in.readBoolean();
|
||||
boolean appendEnv = in.readBoolean();
|
||||
System.err.print("dispatch: ");
|
||||
for (String s:command) {
|
||||
System.err.print(" " + s);
|
||||
StreamChannel cmdChan = server.getChannel(cmdChanId);
|
||||
StreamChannel ioChan = server.getChannel(ioChanId);
|
||||
StreamChannel errChan= server.getChannel(errChanId);
|
||||
if (cmdChan == null || ioChan == null || errChan == null) {
|
||||
throw new ProxyException("Unable to locate channels for command"); //$NON-NLS-1$
|
||||
}
|
||||
System.err.println(" [" + chanAId + "," + chanBId+ ","+ chanCId + "]");
|
||||
StreamChannel chanA = server.getChannel(chanAId);
|
||||
StreamChannel chanB = server.getChannel(chanBId);
|
||||
StreamChannel chanC= server.getChannel(chanCId);
|
||||
if (chanA == null || chanB == null || chanC == null) {
|
||||
throw new ProxyException("Unable to locate channels for command");
|
||||
}
|
||||
return new ServerExecCommand(command, env, dir, redirect, appendEnv, chanA, chanB, chanC);
|
||||
return new ServerExecCommand(command, env, dir, redirect, appendEnv, cmdChan, ioChan, errChan);
|
||||
}
|
||||
|
||||
private AbstractServerCommand cmdShell(DataInputStream in) throws ProxyException, IOException {
|
||||
int cmdChanId = in.readByte();
|
||||
int ioChanId = in.readByte();
|
||||
StreamChannel cmdChan = server.getChannel(cmdChanId);
|
||||
StreamChannel ioChan = server.getChannel(ioChanId);
|
||||
if (cmdChan == null || ioChan == null) {
|
||||
throw new ProxyException("Unable to locate channels for command"); //$NON-NLS-1$
|
||||
}
|
||||
return new ServerShellCommand(cmdChan, ioChan);
|
||||
}
|
||||
private AbstractServerCommand cmdGetCwd(DataInputStream in) throws ProxyException, IOException {
|
||||
int chanId = in.readByte();
|
||||
StreamChannel chan = server.getChannel(chanId);
|
||||
if (chan == null) {
|
||||
throw new ProxyException("Unable to locate channel for command");
|
||||
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||
}
|
||||
return new ServerGetCwdCommand(chan);
|
||||
}
|
||||
|
@ -203,7 +213,7 @@ public class CommandServer implements Runnable {
|
|||
int chanId = in.readByte();
|
||||
StreamChannel chan = server.getChannel(chanId);
|
||||
if (chan == null) {
|
||||
throw new ProxyException("Unable to locate channel for command");
|
||||
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||
}
|
||||
return new ServerGetEnvCommand(chan);
|
||||
}
|
||||
|
@ -212,7 +222,7 @@ public class CommandServer implements Runnable {
|
|||
int chanId = in.readByte();
|
||||
StreamChannel chan = server.getChannel(chanId);
|
||||
if (chan == null) {
|
||||
throw new ProxyException("Unable to locate channel for command");
|
||||
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||
}
|
||||
return new ServerGetPropertiesCommand(chan);
|
||||
}
|
||||
|
@ -221,7 +231,7 @@ public class CommandServer implements Runnable {
|
|||
int chanId = in.readByte();
|
||||
StreamChannel chan = server.getChannel(chanId);
|
||||
if (chan == null) {
|
||||
throw new ProxyException("Unable to locate channel for command");
|
||||
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||
}
|
||||
String path = in.readUTF();
|
||||
return new ServerChildInfosCommand(chan, path);
|
||||
|
@ -231,7 +241,7 @@ public class CommandServer implements Runnable {
|
|||
int chanId = in.readByte();
|
||||
StreamChannel chan = server.getChannel(chanId);
|
||||
if (chan == null) {
|
||||
throw new ProxyException("Unable to locate channel for command");
|
||||
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||
}
|
||||
String path = in.readUTF();
|
||||
return new ServerFetchInfoCommand(chan, path);
|
||||
|
@ -241,7 +251,7 @@ public class CommandServer implements Runnable {
|
|||
int chanId = in.readByte();
|
||||
StreamChannel chan = server.getChannel(chanId);
|
||||
if (chan == null) {
|
||||
throw new ProxyException("Unable to locate channel for command");
|
||||
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||
}
|
||||
int options = in.readInt();
|
||||
String path = in.readUTF();
|
||||
|
@ -252,7 +262,7 @@ public class CommandServer implements Runnable {
|
|||
int chanId = in.readByte();
|
||||
StreamChannel chan = server.getChannel(chanId);
|
||||
if (chan == null) {
|
||||
throw new ProxyException("Unable to locate channel for command");
|
||||
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||
}
|
||||
int options = in.readInt();
|
||||
String path = in.readUTF();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
|
@ -5,14 +5,13 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -23,83 +22,37 @@ import java.util.concurrent.locks.Condition;
|
|||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
||||
/**
|
||||
* TODO: Fix hang if command fails...
|
||||
*
|
||||
*/
|
||||
public class ServerExecCommand extends AbstractServerCommand {
|
||||
|
||||
private final List<String> command;
|
||||
private final Map<String, String> env;
|
||||
private final boolean redirect;
|
||||
private final boolean appendEnv;
|
||||
private final String directory;
|
||||
private final InputStream stdin;
|
||||
private final OutputStream stdout;
|
||||
private final OutputStream stderr;
|
||||
private final DataOutputStream result;
|
||||
private final DataInputStream cmd;
|
||||
|
||||
private Process proc;
|
||||
public abstract class AbstractServerExecCommand extends AbstractServerCommand {
|
||||
|
||||
private class CommandRunner implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
ProcessBuilder builder = new ProcessBuilder(command);
|
||||
try {
|
||||
if (!appendEnv) {
|
||||
builder.environment().clear();
|
||||
builder.environment().putAll(env);
|
||||
} else {
|
||||
for (Map.Entry<String, String> entry : env.entrySet()) {
|
||||
String val = builder.environment().get(entry.getKey());
|
||||
if (val == null || !val.equals(entry.getValue())) {
|
||||
builder.environment().put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedOperationException | IllegalArgumentException e) {
|
||||
// Leave environment untouched
|
||||
}
|
||||
File dir = new File(directory);
|
||||
if (dir.exists() && dir.isAbsolute()) {
|
||||
builder.directory(dir);
|
||||
}
|
||||
builder.redirectErrorStream(redirect);
|
||||
try {
|
||||
int exit = 0;
|
||||
try {
|
||||
proc = builder.start();
|
||||
Forwarder stdoutFwd = startForwarder("stdout", proc.getInputStream(), stdout); //$NON-NLS-1$
|
||||
proc = doRun();
|
||||
Forwarder stdoutFwd = startForwarder("stdout", proc.getInputStream(), stdoutChan); //$NON-NLS-1$
|
||||
Forwarder stderrFwd = null;
|
||||
if (!redirect) {
|
||||
stderrFwd = startForwarder("stderr", proc.getErrorStream(), stderr); //$NON-NLS-1$
|
||||
stderrFwd = startForwarder("stderr", proc.getErrorStream(), stderrChan); //$NON-NLS-1$
|
||||
}
|
||||
startForwarder("stdin", stdin, proc.getOutputStream()); //$NON-NLS-1$
|
||||
startForwarder("stdin", stdinChan, proc.getOutputStream()); //$NON-NLS-1$
|
||||
new Thread(new ProcMonitor(), "process monitor").start(); //$NON-NLS-1$
|
||||
System.err.println("wait for process");
|
||||
exit = proc.waitFor();
|
||||
System.err.println("wait for process close in");
|
||||
// stdoutFwd.terminate();
|
||||
// if (!redirect) {
|
||||
// stderrFwd.terminate();
|
||||
// }
|
||||
System.err.println("wait for readers");
|
||||
/*
|
||||
* After the process has finished, wait for the stdout and stderr forwarders to finish to
|
||||
* ensure that all output is flushed.
|
||||
*/
|
||||
// stdoutFwd.waitFor();
|
||||
// System.err.println("wait for process finished out");
|
||||
// if (stderrFwd != null) {
|
||||
// stderrFwd.waitFor();
|
||||
// }
|
||||
System.err.println("wait for readers done");
|
||||
stdoutFwd.waitFor();
|
||||
if (stderrFwd != null) {
|
||||
stderrFwd.waitFor();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stderr));
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stderrChan));
|
||||
try {
|
||||
writer.write(e.getMessage());
|
||||
writer.flush();
|
||||
|
@ -109,8 +62,8 @@ public class ServerExecCommand extends AbstractServerCommand {
|
|||
exit = -1;
|
||||
}
|
||||
try {
|
||||
result.writeInt(exit);
|
||||
result.flush();
|
||||
resultStream.writeInt(exit);
|
||||
resultStream.flush();
|
||||
} catch (IOException e) {
|
||||
// We're finished anyway
|
||||
}
|
||||
|
@ -124,9 +77,17 @@ public class ServerExecCommand extends AbstractServerCommand {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
cmd.readByte();
|
||||
if (proc.isAlive()) {
|
||||
proc.destroyForcibly();
|
||||
switch (cmdStream.readByte()) {
|
||||
case Protocol.CONTROL_KILL:
|
||||
doKill(proc);
|
||||
break;
|
||||
case Protocol.CONTROL_SETTERMINALSIZE:
|
||||
int cols = cmdStream.readInt();
|
||||
int rows = cmdStream.readInt();
|
||||
cmdStream.readInt(); // pixel dimensions not supported
|
||||
cmdStream.readInt(); // pixel dimensions not supported
|
||||
doSetTerminalSize(proc, cols, rows);
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Finish
|
||||
|
@ -139,8 +100,7 @@ public class ServerExecCommand extends AbstractServerCommand {
|
|||
private final OutputStream out;
|
||||
private final String name;
|
||||
|
||||
private volatile boolean running = true;
|
||||
private boolean terminated = false;
|
||||
private boolean running = true;
|
||||
|
||||
private final Lock lock = new ReentrantLock();
|
||||
private final Condition cond = lock.newCondition();
|
||||
|
@ -156,58 +116,44 @@ public class ServerExecCommand extends AbstractServerCommand {
|
|||
byte[] buf = new byte[8192];
|
||||
int n;
|
||||
try {
|
||||
while (true) {
|
||||
// if (in.available() == 0) {
|
||||
// System.err.println("avail=0");
|
||||
// /* Avoid spinning if no data */
|
||||
// lock.lock();
|
||||
// try {
|
||||
// cond.await(100, TimeUnit.MILLISECONDS);
|
||||
// } catch (InterruptedException e) {
|
||||
// } finally {
|
||||
// lock.unlock();
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
while (running) {
|
||||
n = in.read(buf);
|
||||
if (n > 0) {
|
||||
out.write(buf, 0, n);
|
||||
out.flush();
|
||||
}
|
||||
if (n==0) System.err.println("forwarder n=0");
|
||||
if (n < 0) break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Finish
|
||||
System.err.println("forwarder "+e.getMessage());
|
||||
}
|
||||
System.err.println("forwarder closing name="+name);
|
||||
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
// Best effort
|
||||
}
|
||||
lock.lock();
|
||||
terminated = true;
|
||||
try {
|
||||
running = false;
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
// Best effort
|
||||
}
|
||||
cond.signalAll();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
running = false;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public synchronized void waitFor() {
|
||||
lock.lock();
|
||||
try {
|
||||
if (!terminated) {
|
||||
while (running) {
|
||||
try {
|
||||
cond.await();
|
||||
} catch (InterruptedException e) {
|
||||
// Check terminated flag
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
@ -215,28 +161,71 @@ public class ServerExecCommand extends AbstractServerCommand {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final List<String> command;
|
||||
private final Map<String, String> env;
|
||||
private final boolean redirect;
|
||||
private final boolean appendEnv;
|
||||
private final String directory;
|
||||
|
||||
private final InputStream stdinChan;
|
||||
private final OutputStream stdoutChan;
|
||||
private final OutputStream stderrChan;
|
||||
|
||||
private final DataInputStream cmdStream;
|
||||
private final DataOutputStream resultStream;
|
||||
|
||||
public ServerExecCommand(List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv, StreamChannel chanA, StreamChannel chanB, StreamChannel chanC) {
|
||||
private Process proc;
|
||||
|
||||
public AbstractServerExecCommand(List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv, StreamChannel cmdChan, StreamChannel ioChan, StreamChannel errChan) {
|
||||
this.command = command;
|
||||
this.env = env;
|
||||
this.directory = directory;
|
||||
this.redirect = redirect;
|
||||
this.appendEnv = appendEnv;
|
||||
this.stdin = chanA.getInputStream();
|
||||
this.stdout = chanA.getOutputStream();
|
||||
this.stderr = chanB.getOutputStream();
|
||||
|
||||
this.result = new DataOutputStream(chanC.getOutputStream());
|
||||
this.cmd = new DataInputStream(chanC.getInputStream());
|
||||
this.stdinChan = ioChan.getInputStream();
|
||||
this.stdoutChan = ioChan.getOutputStream();
|
||||
|
||||
this.stderrChan = errChan != null ? errChan.getOutputStream() : this.stdoutChan;
|
||||
|
||||
this.resultStream = new DataOutputStream(cmdChan.getOutputStream());
|
||||
this.cmdStream = new DataInputStream(cmdChan.getInputStream());
|
||||
}
|
||||
|
||||
protected abstract Process doRun() throws IOException;
|
||||
|
||||
protected abstract void doKill(Process proc);
|
||||
|
||||
protected abstract void doSetTerminalSize(Process proc, int col, int rows);
|
||||
|
||||
protected List<String> getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
protected Map<String,String> getEnv() {
|
||||
return env;
|
||||
}
|
||||
|
||||
protected boolean isRedirect() {
|
||||
return redirect;
|
||||
}
|
||||
|
||||
protected boolean isAppendEnv() {
|
||||
return appendEnv;
|
||||
}
|
||||
|
||||
protected String getDirectory() {
|
||||
return directory;
|
||||
}
|
||||
|
||||
public void exec() throws ProxyException {
|
||||
new Thread(new CommandRunner(), command.get(0)).start();
|
||||
new Thread(new CommandRunner()).start();
|
||||
}
|
||||
|
||||
private Forwarder startForwarder(String name, InputStream in, OutputStream out) {
|
||||
Forwarder forwarder = new Forwarder(name, in, out);
|
||||
Thread thread = new Thread(forwarder, command.get(0) + " " + name); //$NON-NLS-1$
|
||||
Thread thread = new Thread(forwarder, forwarder.getName());
|
||||
thread.start();
|
||||
return forwarder;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -15,8 +15,8 @@ import java.net.URI;
|
|||
import org.eclipse.core.filesystem.EFS;
|
||||
import org.eclipse.core.filesystem.IFileInfo;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
||||
public class ServerChildInfosCommand extends AbstractServerCommand {
|
||||
|
@ -45,7 +45,7 @@ public class ServerChildInfosCommand extends AbstractServerCommand {
|
|||
|
||||
public ServerChildInfosCommand(StreamChannel chan, String path) {
|
||||
this.out = chan.getOutputStream();
|
||||
this.uri = URI.create("file:" + path);
|
||||
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void exec() throws ProxyException {
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
|
@ -20,7 +20,7 @@ public class ServerDeleteCommand extends AbstractServerCommand {
|
|||
|
||||
public ServerDeleteCommand(int options, String path) {
|
||||
this.options = options;
|
||||
this.uri = URI.create("file:" + path);
|
||||
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void exec() throws ProxyException {
|
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Oak Ridge National Laboratory and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
|
||||
/**
|
||||
* TODO: Fix hang if command fails...
|
||||
*
|
||||
*/
|
||||
public class ServerExecCommand extends AbstractServerExecCommand {
|
||||
public Process doRun() throws IOException {
|
||||
System.err.print("exec: ");
|
||||
for (String arg:getCommand()) {
|
||||
System.err.print(arg + " ");
|
||||
}
|
||||
System.err.println();
|
||||
ProcessBuilder builder = new ProcessBuilder(getCommand());
|
||||
try {
|
||||
if (!isAppendEnv()) {
|
||||
builder.environment().clear();
|
||||
builder.environment().putAll(getEnv());
|
||||
} else {
|
||||
for (Map.Entry<String, String> entry : getEnv().entrySet()) {
|
||||
String val = builder.environment().get(entry.getKey());
|
||||
if (val == null || !val.equals(entry.getValue())) {
|
||||
builder.environment().put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedOperationException | IllegalArgumentException e) {
|
||||
// Leave environment untouched
|
||||
}
|
||||
File dir = new File(getDirectory());
|
||||
if (dir.exists() && dir.isAbsolute()) {
|
||||
builder.directory(dir);
|
||||
}
|
||||
builder.redirectErrorStream(isRedirect());
|
||||
return builder.start();
|
||||
}
|
||||
|
||||
protected void doKill(Process proc) {
|
||||
if (proc.isAlive()) {
|
||||
proc.destroyForcibly();
|
||||
}
|
||||
}
|
||||
|
||||
protected void doSetTerminalSize(Process proc, int cols, int rows) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
public ServerExecCommand(List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv, StreamChannel cmdChan, StreamChannel ioChan, StreamChannel errChan) {
|
||||
super(command, env, directory, redirect, appendEnv, cmdChan, ioChan, errChan);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -15,8 +15,8 @@ import java.net.URI;
|
|||
import org.eclipse.core.filesystem.EFS;
|
||||
import org.eclipse.core.filesystem.IFileInfo;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||
|
||||
public class ServerFetchInfoCommand extends AbstractServerCommand {
|
||||
|
@ -42,7 +42,7 @@ public class ServerFetchInfoCommand extends AbstractServerCommand {
|
|||
|
||||
public ServerFetchInfoCommand(StreamChannel chan, String path) {
|
||||
this.out = chan.getOutputStream();
|
||||
this.uri = URI.create("file:" + path);
|
||||
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void exec() throws ProxyException {
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -35,7 +35,7 @@ public class ServerGetCwdCommand extends AbstractServerCommand {
|
|||
}
|
||||
|
||||
public void exec() throws ProxyException {
|
||||
cwd = System.getProperty("user.dir");
|
||||
cwd = System.getProperty("user.dir"); //$NON-NLS-1$
|
||||
new Thread(new CommandRunner()).start();
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -32,7 +32,7 @@ public class ServerGetPropertiesCommand extends AbstractServerCommand {
|
|||
props.put(IRemoteConnection.OS_NAME_PROPERTY, System.getProperty(IRemoteConnection.OS_NAME_PROPERTY));
|
||||
props.put(IRemoteConnection.OS_VERSION_PROPERTY, System.getProperty(IRemoteConnection.OS_VERSION_PROPERTY));
|
||||
props.put(IRemoteConnection.OS_ARCH_PROPERTY, System.getProperty(IRemoteConnection.OS_ARCH_PROPERTY));
|
||||
props.put(IRemoteConnection.LOCALE_CHARMAP_PROPERTY, System.getProperty("file.encoding"));
|
||||
props.put(IRemoteConnection.LOCALE_CHARMAP_PROPERTY, System.getProperty("file.encoding")); //$NON-NLS-1$
|
||||
|
||||
result.writeInt(props.size());
|
||||
for (Map.Entry<String, String> entry : props.entrySet()) {
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
|
@ -20,7 +20,7 @@ public class ServerMkdirCommand extends AbstractServerCommand {
|
|||
|
||||
public ServerMkdirCommand(int options, String path) {
|
||||
this.options = options;
|
||||
this.uri = URI.create("file:" + path);
|
||||
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void exec() throws ProxyException {
|
|
@ -5,7 +5,7 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.commands;
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class ServerPutInfoCommand extends AbstractServerCommand {
|
|||
public ServerPutInfoCommand(IFileInfo info, int options, String path) {
|
||||
this.info = info;
|
||||
this.options = options;
|
||||
this.uri = URI.create("file:" + path);
|
||||
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void exec() throws ProxyException {
|
|
@ -0,0 +1,178 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Oak Ridge National Laboratory and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.cdt.utils.pty.PTY;
|
||||
import org.eclipse.cdt.utils.pty.PTY.Mode;
|
||||
import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||
|
||||
/**
|
||||
* TODO: Fix hang if command fails...
|
||||
*
|
||||
*/
|
||||
public class ServerShellCommand extends AbstractServerExecCommand {
|
||||
private class ShellProcess extends Process {
|
||||
private final Process proc;
|
||||
private final PTY pty;
|
||||
|
||||
public ShellProcess(Process proc, PTY pty) {
|
||||
this.proc = proc;
|
||||
this.pty = pty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() {
|
||||
if (pty != null) {
|
||||
return pty.getOutputStream();
|
||||
}
|
||||
return proc.getOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
if (pty != null) {
|
||||
return pty.getInputStream();
|
||||
}
|
||||
return proc.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getErrorStream() {
|
||||
if (pty != null) {
|
||||
return pty.getInputStream();
|
||||
}
|
||||
return proc.getErrorStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int waitFor() throws InterruptedException {
|
||||
return proc.waitFor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int exitValue() {
|
||||
return proc.exitValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
proc.destroy();
|
||||
}
|
||||
|
||||
public void setTerminalSize(int cols, int rows) {
|
||||
if (pty != null) {
|
||||
pty.setTerminalSize(cols, rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ServerShellCommand(StreamChannel cmdChan, StreamChannel ioChan) {
|
||||
super(null, null, null, true, false, cmdChan, ioChan, null);
|
||||
}
|
||||
|
||||
public Process doRun() throws IOException {
|
||||
String shell = findLoginShell();
|
||||
|
||||
if (PTY.isSupported(Mode.TERMINAL)) {
|
||||
PTY pty = new PTY(Mode.TERMINAL);
|
||||
Process p = ProcessFactory.getFactory().exec(new String[] {shell, "-l"}, null, null, pty); //$NON-NLS-1$
|
||||
return new ShellProcess(p, pty);
|
||||
}
|
||||
|
||||
return ProcessFactory.getFactory().exec(new String[] {shell, "-l"}, null, null); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
protected void doKill(Process proc) {
|
||||
if (proc.isAlive()) {
|
||||
proc.destroyForcibly();
|
||||
}
|
||||
}
|
||||
|
||||
protected void doSetTerminalSize(Process proc, int cols, int rows) {
|
||||
if (proc.isAlive() && proc instanceof ShellProcess) {
|
||||
ShellProcess shell = (ShellProcess)proc;
|
||||
shell.setTerminalSize(cols, rows);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the login shell.
|
||||
*
|
||||
* On Linux, use `getent passwd $USER`
|
||||
* On Mac OSX, use `dscl . -read /Users/$USER UserShell`
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String findLoginShell() throws IOException {
|
||||
String res;
|
||||
|
||||
String osName = System.getProperty("os.name"); //$NON-NLS-1$
|
||||
String userName = System.getProperty("user.name"); //$NON-NLS-1$
|
||||
if (osName == null || userName == null) {
|
||||
throw new IOException("Unable to obtain information needed to find login shell"); //$NON-NLS-1$
|
||||
}
|
||||
switch (osName) {
|
||||
case "Mac OS X": //$NON-NLS-1$
|
||||
res = executeCommand("dscl . -read /Users/" + userName + " UserShell"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if (res != null) {
|
||||
String[] vals = res.split(" "); //$NON-NLS-1$
|
||||
if (vals.length == 2) {
|
||||
return vals[1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Linux": //$NON-NLS-1$
|
||||
res = executeCommand("getent passwd " + userName); //$NON-NLS-1$
|
||||
if (res != null) {
|
||||
String[] vals = res.split(":"); //$NON-NLS-1$
|
||||
if (vals.length == 7) {
|
||||
return vals[6];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw new IOException("Unable to find login shell for os=" + osName + " user=" + userName); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
private String executeCommand(String command) throws IOException {
|
||||
String line;
|
||||
StringBuffer output = new StringBuffer();
|
||||
|
||||
Process p;
|
||||
try {
|
||||
p = Runtime.getRuntime().exec(command);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
try {
|
||||
p.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
line = reader.readLine();
|
||||
while (line != null) {
|
||||
output.append(line);
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
output.append("\n"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
return output.toString();
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
<windowImages/>
|
||||
|
||||
<launcher name="proxy">
|
||||
<solaris/>
|
||||
<win useIco="false">
|
||||
<bmp/>
|
||||
</win>
|
||||
|
@ -28,6 +27,8 @@
|
|||
|
||||
<plugins>
|
||||
<plugin id="com.ibm.icu"/>
|
||||
<plugin id="org.eclipse.cdt.core.macosx" fragment="true"/>
|
||||
<plugin id="org.eclipse.cdt.core.linux.x86_64" fragment="true"/>
|
||||
<plugin id="org.eclipse.cdt.core.native"/>
|
||||
<plugin id="org.eclipse.core.contenttype"/>
|
||||
<plugin id="org.eclipse.core.expressions"/>
|
||||
|
@ -53,10 +54,6 @@
|
|||
<plugin id="org.eclipse.remote.proxy.server.core"/>
|
||||
</plugins>
|
||||
|
||||
<features>
|
||||
<feature id="org.eclipse.remote.proxy"/>
|
||||
</features>
|
||||
|
||||
<configurations>
|
||||
<plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="0" />
|
||||
<plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?pde version="3.8"?>
|
||||
<target name="remote-oxygen" sequenceNumber="0">
|
||||
<?pde version="3.8"?><target name="remote-oxygen" sequenceNumber="0">
|
||||
<locations>
|
||||
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
||||
<unit id="org.eclipse.sdk.ide" version="0.0.0"/>
|
||||
<unit id="org.eclipse.equinox.executable.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.sdk.ide" version="0.0.0"/>
|
||||
<repository location="http://download.eclipse.org/eclipse/updates/4.7/"/>
|
||||
</location>
|
||||
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
||||
<unit id="org.mockito" version="0.0.0"/>
|
||||
<unit id="org.hamcrest" version="0.0.0"/>
|
||||
<unit id="org.mockito" version="0.0.0"/>
|
||||
<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20170919201930/repository/"/>
|
||||
</location>
|
||||
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
||||
<unit id="org.eclipse.cdt.native.serial" version="0.0.0"/>
|
||||
<unit id="org.eclipse.cdt.core" version="0.0.0"/>
|
||||
<unit id="org.eclipse.cdt.native.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.cdt.native.serial" version="0.0.0"/>
|
||||
<repository location="http://download.eclipse.org/tools/cdt/builds/master/nightly/"/>
|
||||
</location>
|
||||
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
||||
|
|
Loading…
Add table
Reference in a new issue