1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-05 08:46:02 +02:00

Bug 452356 - C/C++ remote launch uses o.e.remote

Replaced RSE with o.e.remote on C/C++ remote run
 and debug launchers.

Change-Id: I308b81ad90ae8e838557d7b2afb53efb1cdf7ff9
Signed-off-by: Wainer dos Santos Moschetta <wainersm@linux.vnet.ibm.com>
This commit is contained in:
Wainer dos Santos Moschetta 2016-03-09 14:33:28 -03:00 committed by Gerrit Code Review @ Eclipse.org
parent 7ca2032810
commit eb5ac1a56b
14 changed files with 568 additions and 560 deletions

View file

@ -2,15 +2,10 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: %pluginName Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.launch.remote;singleton:=true Bundle-SymbolicName: org.eclipse.cdt.launch.remote;singleton:=true
Bundle-Version: 2.4.0.qualifier Bundle-Version: 2.5.0.qualifier
Bundle-Activator: org.eclipse.cdt.internal.launch.remote.Activator Bundle-Activator: org.eclipse.cdt.internal.launch.remote.Activator
Bundle-Localization: plugin Bundle-Localization: plugin
Require-Bundle: org.eclipse.rse.ui;bundle-version="[3.0.0,4.0.0)", Require-Bundle: org.eclipse.cdt.launch,
org.eclipse.rse.subsystems.shells.core;bundle-version="[3.0.0,4.0.0)",
org.eclipse.rse.subsystems.files.core;bundle-version="[3.0.0,4.0.0)",
org.eclipse.rse.core;bundle-version="[3.0.0,4.0.0)",
org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)",
org.eclipse.cdt.launch,
org.eclipse.cdt.debug.core, org.eclipse.cdt.debug.core,
org.eclipse.cdt.core, org.eclipse.cdt.core,
org.eclipse.debug.ui, org.eclipse.debug.ui,
@ -19,11 +14,13 @@ Require-Bundle: org.eclipse.rse.ui;bundle-version="[3.0.0,4.0.0)",
org.eclipse.core.resources, org.eclipse.core.resources,
org.eclipse.core.runtime, org.eclipse.core.runtime,
org.eclipse.cdt.debug.ui, org.eclipse.cdt.debug.ui,
org.eclipse.rse.files.ui;bundle-version="[3.0.0,4.0.0)",
org.eclipse.cdt.dsf.gdb;bundle-version="3.0.0", org.eclipse.cdt.dsf.gdb;bundle-version="3.0.0",
org.eclipse.cdt.dsf.gdb.ui;bundle-version="2.1.0", org.eclipse.cdt.dsf.gdb.ui;bundle-version="2.1.0",
org.eclipse.cdt.dsf;bundle-version="2.1.0", org.eclipse.cdt.dsf;bundle-version="2.1.0",
org.eclipse.core.variables;bundle-version="3.2.300" org.eclipse.core.variables;bundle-version="3.2.300",
org.eclipse.remote.core;bundle-version="2.0.0",
org.eclipse.remote.ui;bundle-version="2.0.0",
org.eclipse.core.filesystem
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Eclipse-LazyStart: true Eclipse-LazyStart: true
Bundle-Vendor: %providerName Bundle-Vendor: %providerName

View file

@ -11,7 +11,7 @@
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<version>2.4.0-SNAPSHOT</version> <version>2.5.0-SNAPSHOT</version>
<artifactId>org.eclipse.cdt.launch.remote</artifactId> <artifactId>org.eclipse.cdt.launch.remote</artifactId>
<packaging>eclipse-plugin</packaging> <packaging>eclipse-plugin</packaging>
</project> </project>

View file

@ -4,7 +4,7 @@
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="copyright" content="Copyright (c) 2006, 2007 PalmSource, Inc. and others. This page is made available under license. For full details see the LEGAL notice in the documentation book that contains this page." /> <meta name="copyright" content="Copyright (c) 2006, 2007 PalmSource, Inc. and others. This page is made available under license. For full details see the LEGAL notice in the documentation book that contains this page." />
<link rel="stylesheet" type="text/css" href="../org.eclipse.rse.doc.user/book.css" /> <link rel="stylesheet" type="text/css" href="../org.eclipse.cdt.doc.user/book.css" />
<title>Launching Remote C/C++ Applications</title> <title>Launching Remote C/C++ Applications</title>
</head> </head>
<!-- <!--
@ -18,30 +18,30 @@ Contributors:
Ewa Matejska (PalmSource) - initial API and implementation Ewa Matejska (PalmSource) - initial API and implementation
Martin Oberhuber (Wind River) - fix 158529: Migrate docs to HTML / TOC format Martin Oberhuber (Wind River) - fix 158529: Migrate docs to HTML / TOC format
Dave Dykstal (IBM) - fix 174770: SAX Parse exceptions in Eclipse 3.3 Dave Dykstal (IBM) - fix 174770: SAX Parse exceptions in Eclipse 3.3
Wainer S. Moschetta (IBM) - bug 452356: replace RSE with org.eclipse.remote
--> -->
<body id="tremotecdt"><a name="tremotecdt"><!-- --></a> <body id="tremotecdt"><a name="tremotecdt"><!-- --></a>
<h1 class="topictitle1">Launching Remote C/C++ Applications</h1> <h1 class="topictitle1">Launching Remote C/C++ Applications</h1>
<div class="p"> <div class="p">
<p>The RSE Remote CDT Plugin builds on top of CDT and integrates with RSE to introduce <p>The remote CDT launch Plugin builds on top of CDT and integrates with Eclipse remote framework (org.eclipse.remote)
a "Remote C/C++ Application" launch configuration. This launch configuration relies to introduce a "Remote C/C++ Application" launch configuration. This launch configuration relies
on the shell and file services of the RSE connections.</p> on the shell and file services of the remote framework's connections.</p>
<p>The "Remote C/C++ Application" launch configuration enables the user to select from a list of RSE <p>The "Remote C/C++ Application" launch configuration enables the user to select from a list of connections which have the shell service available. For a debug launch, the binary is downloaded
connections which have the shell service available. For a debug launch, the binary is downloaded to the remote using the file service of the remote framework's connection, gdbserver is automatically started
to the remote using the file service of the RSE connection, gdbserver is automatically started
on the remote using the shell service and a gdb debug connection is establised. For a run launch, on the remote using the shell service and a gdb debug connection is establised. For a run launch,
the binary is downloaded to the remote using the file service and then it is invoked using the shell the binary is downloaded to the remote using the file service and then it is invoked using the shell
service.</p> service.</p>
<p>In the future, an RSE file service should be used to select where the remote download <p>In the future, a file service should be used to select where the remote download
should take place. Right now the remote path is entered manually in a text field.</p> should take place. Right now the remote path is entered manually in a text field.</p>
</div> </div>
<h2>System Prerequisites</h2> <h2>System Prerequisites</h2>
<div class="p"><b>Local Host</b> <div class="p"><b>Local Host</b>
<ul> <ul>
<li>It is necessary to create an RSE connection which has the file and shell services <li>It is necessary to create an connection which has the file and shell services
available.</li> available.</li>
</ul></div> </ul></div>

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.launch.remote;
import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/** /**
* The main plugin class to be used in the desktop. * The main plugin class to be used in the desktop.
@ -64,4 +65,16 @@ public class Activator extends Plugin {
public static BundleContext getBundleContext() { public static BundleContext getBundleContext() {
return getDefault().getBundle().getBundleContext(); return getDefault().getBundle().getBundleContext();
} }
/**
* Return the OSGi service with the given service interface.
*
* @param service service interface
* @return the specified service or null if it's not registered
*/
public static <T> T getService(Class<T> service) {
BundleContext context = Activator.getBundleContext();
ServiceReference<T> ref = context.getServiceReference(service);
return ref != null ? context.getService(ref) : null;
}
} }

View file

@ -43,6 +43,8 @@ public class Messages extends NLS {
public static String RemoteCMainTab_ErrorNoConnection; public static String RemoteCMainTab_ErrorNoConnection;
public static String RemoteCMainTab_Connection; public static String RemoteCMainTab_Connection;
public static String RemoteCMainTab_New; public static String RemoteCMainTab_New;
public static String RemoteCMainTab_New_title;
public static String RemoteCMainTab_New_conntype_combo_label;
public static String RemoteCMainTab_Edit; public static String RemoteCMainTab_Edit;
public static String RemoteCMainTab_Properties; public static String RemoteCMainTab_Properties;
public static String RemoteCMainTab_Properties_title; public static String RemoteCMainTab_Properties_title;

View file

@ -43,6 +43,8 @@ RemoteCMainTab_ErrorNoConnection=Remote Connection must be selected.
RemoteCMainTab_Remote_Path_Browse_Button=Browse... RemoteCMainTab_Remote_Path_Browse_Button=Browse...
RemoteCMainTab_Connection=Connection: RemoteCMainTab_Connection=Connection:
RemoteCMainTab_New=New... RemoteCMainTab_New=New...
RemoteCMainTab_New_title=Create a new connection
RemoteCMainTab_New_conntype_combo_label=Choose connection type:
RemoteCMainTab_Edit=Edit... RemoteCMainTab_Edit=Edit...
Gdbserver_Settings_Tab_Name=Gdbserver Settings Gdbserver_Settings_Tab_Name=Gdbserver Settings
Gdbserver_name_textfield_label=Gdbserver path: Gdbserver_name_textfield_label=Gdbserver path:

View file

@ -26,7 +26,7 @@ package org.eclipse.cdt.launch.remote;
*/ */
public interface IRemoteConnectionHostConstants { public interface IRemoteConnectionHostConstants {
public static final String PI_REMOTE_CDT = "org.eclipse.rse.remotecdt"; //$NON-NLS-1$ public static final String PI_REMOTE_CDT = "org.eclipse.cdt.launch.remote.attr"; //$NON-NLS-1$
public static final String REMOTE_WS_ROOT = "remoteWsRoot"; //$NON-NLS-1$ public static final String REMOTE_WS_ROOT = "remoteWsRoot"; //$NON-NLS-1$
public static final String DEFAULT_SKIP_DOWNLOAD = "defaultSkipDownload"; //$NON-NLS-1$ public static final String DEFAULT_SKIP_DOWNLOAD = "defaultSkipDownload"; //$NON-NLS-1$

View file

@ -1,354 +0,0 @@
/********************************************************************************
* Copyright (c) 2009, 2016 MontaVista Software, Inc. and others.
* 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:
* Anna Dushistova (MontaVista) - initial API and implementation
* Anna Dushistova (Mentor Graphics) - [314659] moved common methods for DSF and CDI launches to this class
* Anna Dushistova (Mentor Graphics) - changed spaceEscapify visibility
* Anna Dushistova (MontaVista) - [318051][remote debug] Terminating when "Remote shell" process is selected doesn't work
********************************************************************************/
package org.eclipse.cdt.launch.remote;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.internal.launch.remote.Activator;
import org.eclipse.cdt.internal.launch.remote.Messages;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.osgi.util.NLS;
import org.eclipse.rse.core.RSECorePlugin;
import org.eclipse.rse.core.model.IHost;
import org.eclipse.rse.core.subsystems.ISubSystem;
import org.eclipse.rse.services.IService;
import org.eclipse.rse.services.clientserver.messages.SystemOperationCancelledException;
import org.eclipse.rse.services.files.IFileService;
import org.eclipse.rse.services.shells.HostShellProcessAdapter;
import org.eclipse.rse.services.shells.IHostShell;
import org.eclipse.rse.services.shells.IShellService;
import org.eclipse.rse.subsystems.files.core.servicesubsystem.IFileServiceSubSystem;
public class RSEHelper {
private final static String EXIT_CMD = "exit"; //$NON-NLS-1$
private final static String CMD_DELIMITER = ";"; //$NON-NLS-1$
public static IHost getRemoteConnectionByName(String remoteConnection) {
if (remoteConnection == null)
return null;
IHost[] connections = RSECorePlugin.getTheSystemRegistry().getHosts();
for (int i = 0; i < connections.length; i++)
if (connections[i].getAliasName().equals(remoteConnection))
return connections[i];
return null; // TODO Connection is not found in the list--need to react
// somehow, throw the exception?
}
public static IService getConnectedRemoteFileService(
IHost currentConnection, IProgressMonitor monitor) throws Exception {
final ISubSystem subsystem = getFileSubsystem(currentConnection);
if (subsystem == null)
throw new Exception(Messages.RemoteRunLaunchDelegate_4);
try {
subsystem.connect(monitor, false);
} catch (CoreException e) {
throw e;
} catch (OperationCanceledException e) {
throw new CoreException(Status.CANCEL_STATUS);
}
if (!subsystem.isConnected())
throw new Exception(Messages.RemoteRunLaunchDelegate_5);
return ((IFileServiceSubSystem) subsystem).getFileService();
}
public static IService getConnectedRemoteShellService(
IHost currentConnection, IProgressMonitor monitor) throws Exception {
ISubSystem subsystem = getSubSystemWithShellService(currentConnection);
if (subsystem != null) {
try {
subsystem.connect(monitor, false);
} catch (CoreException e) {
throw e;
} catch (OperationCanceledException e) {
throw new CoreException(Status.CANCEL_STATUS);
}
if (!subsystem.isConnected())
throw new Exception(Messages.RemoteRunLaunchDelegate_5);
return subsystem.getSubSystemConfiguration()
.getService(currentConnection).getAdapter(
IShellService.class);
} else {
throw new Exception(Messages.RemoteRunLaunchDelegate_4);
}
}
/**
* Find the first shell service associated with the host.
*
* @param host
* the connection
* @return shell service object, or <code>null</code> if not found.
*/
public static IShellService getShellService(IHost host) {
ISubSystem ss = getSubSystemWithShellService(host);
if (ss != null) {
return ss.getSubSystemConfiguration().getService(
host).getAdapter(IShellService.class);
}
return null;
}
/**
* Find the first IShellServiceSubSystem service associated with the host.
*
* @param host
* the connection
* @return shell service subsystem, or <code>null</code> if not found.
*/
public static ISubSystem getSubSystemWithShellService(IHost host) {
if (host == null)
return null;
ISubSystem[] subSystems = host.getSubSystems();
IShellService ssvc = null;
for (int i = 0; subSystems != null && i < subSystems.length; i++) {
IService svc = subSystems[i].getSubSystemConfiguration()
.getService(host);
if (svc != null) {
ssvc = svc.getAdapter(IShellService.class);
if (ssvc != null) {
return subSystems[i];
}
}
}
return null;
}
public static ISubSystem getFileSubsystem(IHost host) {
if (host == null)
return null;
ISubSystem[] subSystems = host.getSubSystems();
for (int i = 0; i < subSystems.length; i++) {
if (subSystems[i] instanceof IFileServiceSubSystem)
return subSystems[i];
}
return null;
}
public static IHost[] getSuitableConnections() {
ArrayList shellConnections = new ArrayList(Arrays.asList(RSECorePlugin.getTheSystemRegistry()
.getHostsBySubSystemConfigurationCategory("shells"))); //$NON-NLS-1$
ArrayList terminalConnections = new ArrayList(Arrays.asList(RSECorePlugin.getTheSystemRegistry()
.getHostsBySubSystemConfigurationCategory("terminals")));//$NON-NLS-1$
Iterator iter = terminalConnections.iterator();
while(iter.hasNext()){
Object terminalConnection = iter.next();
if(!shellConnections.contains(terminalConnection)){
shellConnections.add(terminalConnection);
}
}
return (IHost[]) shellConnections.toArray(new IHost[shellConnections.size()]);
}
public static void remoteFileDownload(ILaunchConfiguration config,
ILaunch launch, String localExePath, String remoteExePath,
IProgressMonitor monitor) throws CoreException {
boolean skipDownload = config
.getAttribute(
IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET,
false);
if (skipDownload)
// Nothing to do. Download is skipped.
return;
monitor.beginTask(Messages.RemoteRunLaunchDelegate_2, 100);
IFileService fileService;
try {
fileService = (IFileService) RSEHelper
.getConnectedRemoteFileService(
getCurrentConnection(config),
new SubProgressMonitor(monitor, 10));
File file = new File(localExePath);
Path remotePath = new Path(remoteExePath);
fileService.upload(file, remotePath.removeLastSegments(1)
.toString(), remotePath.lastSegment(), true, null, null,
new SubProgressMonitor(monitor, 85));
// Need to change the permissions to match the original file
// permissions because of a bug in upload
remoteShellExec(
config,
"", "chmod", "+x " + spaceEscapify(remotePath.toString()), new SubProgressMonitor(monitor, 5)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} catch (SystemOperationCancelledException e) {
abort(e.getLocalizedMessage(), null, IStatus.CANCEL);
} catch (Exception e) {
abort(Messages.RemoteRunLaunchDelegate_6, e,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
} finally {
monitor.done();
}
}
public static String spaceEscapify(String inputString) {
if (inputString == null)
return null;
return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$
}
public static IHost getCurrentConnection(ILaunchConfiguration config)
throws CoreException {
String remoteConnection = config.getAttribute(
IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION,
""); //$NON-NLS-1$
IHost connection = RSEHelper
.getRemoteConnectionByName(remoteConnection);
if (connection == null) {
abort(Messages.RemoteRunLaunchDelegate_13, null,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
}
return connection;
}
public static Process remoteShellExec(ILaunchConfiguration config,
String prelaunchCmd, String remoteCommandPath, String arguments,
IProgressMonitor monitor) throws CoreException {
// The exit command is called to force the remote shell to close after
// our command
// is executed. This is to prevent a running process at the end of the
// debug session.
// See Bug 158786.
monitor.beginTask(NLS.bind(Messages.RemoteRunLaunchDelegate_8,
remoteCommandPath, arguments), 10);
String realRemoteCommand = arguments == null ? spaceEscapify(remoteCommandPath)
: spaceEscapify(remoteCommandPath) + " " + arguments; //$NON-NLS-1$
String remoteCommand = realRemoteCommand + CMD_DELIMITER + EXIT_CMD;
if (!prelaunchCmd.trim().isEmpty())
remoteCommand = prelaunchCmd + CMD_DELIMITER + remoteCommand;
IShellService shellService;
Process p = null;
try {
shellService = (IShellService) RSEHelper
.getConnectedRemoteShellService(
getCurrentConnection(config),
new SubProgressMonitor(monitor, 7));
// This is necessary because runCommand does not actually run the
// command right now.
String env[] = new String[0];
try {
IHostShell hostShell = shellService.launchShell(
"", env, new SubProgressMonitor(monitor, 3)); //$NON-NLS-1$
hostShell.writeToShell(remoteCommand);
p = new HostShellProcessAdapter(hostShell);
} catch (Exception e) {
if (p != null) {
p.destroy();
}
abort(Messages.RemoteRunLaunchDelegate_7, e,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
}
} catch (Exception e1) {
abort(e1.getMessage(), e1,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
}
monitor.done();
return p;
}
public static IHostShell execCmdInRemoteShell(ILaunchConfiguration config,
String prelaunchCmd, String remoteCommandPath, String arguments,
IProgressMonitor monitor) throws Exception {
// The exit command is called to force the remote shell to close after
// our command
// is executed. This is to prevent a running process at the end of the
// debug session.
// See Bug 158786.
monitor.beginTask(NLS.bind(Messages.RemoteRunLaunchDelegate_8,
remoteCommandPath, arguments), 10);
String realRemoteCommand = arguments == null ? spaceEscapify(remoteCommandPath)
: spaceEscapify(remoteCommandPath) + " " + arguments; //$NON-NLS-1$
String remoteCommand = realRemoteCommand + CMD_DELIMITER + EXIT_CMD;
if (!prelaunchCmd.trim().isEmpty())
remoteCommand = prelaunchCmd + CMD_DELIMITER + remoteCommand;
IShellService shellService = null;
shellService = (IShellService) RSEHelper
.getConnectedRemoteShellService(getCurrentConnection(config),
new SubProgressMonitor(monitor, 7));
// This is necessary because runCommand does not actually run the
// command right now.
String env[] = new String[0];
IHostShell hostShell = null;
if (shellService != null) {
hostShell = shellService.launchShell(
"", env, new SubProgressMonitor(monitor, 3)); //$NON-NLS-1$
hostShell.writeToShell(remoteCommand);
}
monitor.done();
return hostShell;
}
public static String getRemoteHostname(ILaunchConfiguration config)
throws CoreException {
IHost currentConnection = getCurrentConnection(config);
return currentConnection.getHostName();
}
/**
* Throws a core exception with an error status object built from the given
* message, lower level exception, and error code.
*
* @param message
* the status message
* @param exception
* lower level exception associated with the error, or
* <code>null</code> if none
* @param code
* error code
*/
public static void abort(String message, Throwable exception, int code) throws CoreException {
IStatus status;
if (exception != null) {
MultiStatus multiStatus = new MultiStatus(Activator.PLUGIN_ID, code, message, exception);
multiStatus.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, code, exception.getLocalizedMessage(), exception));
status= multiStatus;
} else {
status= new Status(IStatus.ERROR, Activator.PLUGIN_ID, code, message, null);
}
throw new CoreException(status);
}
}

View file

@ -0,0 +1,247 @@
/********************************************************************************
* Copyright (c) 2009, 2015 MontaVista Software, Inc. and others.
* 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:
* Anna Dushistova (MontaVista) - initial API and implementation
* Anna Dushistova (Mentor Graphics) - [314659] moved common methods for DSF and CDI launches to this class
* Anna Dushistova (Mentor Graphics) - changed spaceEscapify visibility
* Anna Dushistova (MontaVista) - [318051][remote debug] Terminating when "Remote shell" process is selected doesn't work
* Wainer Moschetta(IBM) - [452356] replace RSE with org.eclipse.remote
********************************************************************************/
package org.eclipse.cdt.launch.remote;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.internal.launch.remote.Activator;
import org.eclipse.cdt.internal.launch.remote.Messages;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.IFileSystem;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.osgi.util.NLS;
import org.eclipse.remote.core.IRemoteCommandShellService;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionHostService;
import org.eclipse.remote.core.IRemoteFileService;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.core.IRemoteServicesManager;
import org.eclipse.remote.core.RemoteProcessAdapter;
public class RemoteHelper {
private final static String EXIT_CMD = "exit"; //$NON-NLS-1$
private final static String CMD_DELIMITER = ";"; //$NON-NLS-1$
public static IRemoteConnection getRemoteConnectionByName(String remoteConnection) {
if (remoteConnection == null)
return null;
IRemoteServicesManager manager = Activator.getService(IRemoteServicesManager.class);
if (manager == null) {
return null;
}
List<IRemoteConnection> conns = manager.getAllRemoteConnections();
for (IRemoteConnection conn: conns) {
if (conn.getName().contentEquals(remoteConnection)) {
return conn;
}
}
return null;
}
public static IRemoteFileService getFileSubsystem(IRemoteConnection conn) {
if (conn == null) {
return null;
}
return conn.getService(IRemoteFileService.class);
}
public static IRemoteConnection[] getSuitableConnections() {
IRemoteServicesManager manager = Activator.getService(IRemoteServicesManager.class);
if (manager == null)
return null;
ArrayList<IRemoteConnection> suitableConnections = new ArrayList<>();
List<IRemoteConnection> allConnections = manager.getAllRemoteConnections();
for (IRemoteConnection conn: allConnections) {
if (conn.hasService(IRemoteCommandShellService.class)) {
suitableConnections.add(conn);
}
}
return suitableConnections.toArray(new IRemoteConnection[]{});
}
public static void remoteFileDownload(ILaunchConfiguration config,
ILaunch launch, String localExePath, String remoteExePath,
IProgressMonitor monitor) throws CoreException {
boolean skipDownload = config
.getAttribute(
IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET,
false);
if (skipDownload)
// Nothing to do. Download is skipped.
return;
monitor.beginTask(Messages.RemoteRunLaunchDelegate_2, 100);
try {
IRemoteConnection conn = getCurrentConnection(config);
IRemoteFileService fs = conn.getService(IRemoteFileService.class);
IFileStore remoteFile = fs.getResource(remoteExePath);
IFileSystem localfs = EFS.getLocalFileSystem();
IFileStore localFile = localfs.getStore(new Path(localExePath));
if (!localFile.fetchInfo().exists()) {
return;
}
localFile.copy(remoteFile, EFS.OVERWRITE, monitor);
// Need to change the permissions to match the original file
// permissions because of a bug in upload
remoteShellExec(
config,
"", "chmod", "+x " + spaceEscapify(remoteExePath), new SubProgressMonitor(monitor, 5)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} catch (CoreException e) {
abort(Messages.RemoteRunLaunchDelegate_6, e,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
} finally {
monitor.done();
}
}
public static String spaceEscapify(String inputString) {
if (inputString == null)
return null;
return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$
}
public static IRemoteConnection getCurrentConnection(ILaunchConfiguration config)
throws CoreException {
String remoteConnection = config.getAttribute(
IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION,
""); //$NON-NLS-1$
IRemoteConnection connection = getRemoteConnectionByName(remoteConnection);
if (connection == null) {
abort(Messages.RemoteRunLaunchDelegate_13, null,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
}
return connection;
}
public static Process remoteShellExec(ILaunchConfiguration config,
String prelaunchCmd, String remoteCommandPath, String arguments,
IProgressMonitor monitor) throws CoreException {
// The exit command is called to force the remote shell to close after
// our command
// is executed. This is to prevent a running process at the end of the
// debug session.
// See Bug 158786.
monitor.beginTask(NLS.bind(Messages.RemoteRunLaunchDelegate_8,
remoteCommandPath, arguments), 10);
String realRemoteCommand = arguments == null ? spaceEscapify(remoteCommandPath)
: spaceEscapify(remoteCommandPath) + " " + arguments; //$NON-NLS-1$
String remoteCommand = realRemoteCommand + CMD_DELIMITER + EXIT_CMD + "\r\n"; //$NON-NLS-1$
if (!prelaunchCmd.trim().equals("")) //$NON-NLS-1$
remoteCommand = prelaunchCmd + CMD_DELIMITER + remoteCommand;
IRemoteConnection conn = getCurrentConnection(config);
IRemoteCommandShellService shellService = conn.getService(IRemoteCommandShellService.class);
IRemoteProcess remoteProcess = null;
Process p = null;
try {
remoteProcess = shellService.getCommandShell(IRemoteProcessBuilder.ALLOCATE_PTY);
p = new RemoteProcessAdapter(remoteProcess);
OutputStream os = remoteProcess.getOutputStream();
os.write(remoteCommand.getBytes());
os.flush();
} catch (IOException e) {
abort(Messages.RemoteRunLaunchDelegate_7, e,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
}
monitor.done();
return p;
}
public static IRemoteProcess execCmdInRemoteShell(ILaunchConfiguration config,
String prelaunchCmd, String remoteCommandPath, String arguments,
IProgressMonitor monitor) throws Exception {
// The exit command is called to force the remote shell to close after
// our command
// is executed. This is to prevent a running process at the end of the
// debug session.
// See Bug 158786.
monitor.beginTask(NLS.bind(Messages.RemoteRunLaunchDelegate_8,
remoteCommandPath, arguments), 10);
String realRemoteCommand = arguments == null ? spaceEscapify(remoteCommandPath)
: spaceEscapify(remoteCommandPath) + " " + arguments; //$NON-NLS-1$
String remoteCommand = realRemoteCommand + CMD_DELIMITER + EXIT_CMD + "\r\n"; //$NON-NLS-1$
if (!prelaunchCmd.trim().equals("")) //$NON-NLS-1$
remoteCommand = prelaunchCmd + CMD_DELIMITER + remoteCommand;
IRemoteConnection conn = getCurrentConnection(config);
IRemoteCommandShellService shellService = conn.getService(IRemoteCommandShellService.class);
IRemoteProcess p = null;
p = shellService.getCommandShell(IRemoteProcessBuilder.ALLOCATE_PTY);
OutputStream os = p.getOutputStream();
os.write(remoteCommand.getBytes());
os.flush();
monitor.done();
return p;
}
public static String getRemoteHostname(ILaunchConfiguration config)
throws CoreException {
IRemoteConnection currentConnection = getCurrentConnection(config);
IRemoteConnectionHostService hostService = currentConnection.getService(IRemoteConnectionHostService.class);
return hostService.getHostname();
}
/**
* Throws a core exception with an error status object built from the given
* message, lower level exception, and error code.
*
* @param message
* the status message
* @param exception
* lower level exception associated with the error, or
* <code>null</code> if none
* @param code
* error code
*/
public static void abort(String message, Throwable exception, int code) throws CoreException {
IStatus status;
if (exception != null) {
MultiStatus multiStatus = new MultiStatus(Activator.PLUGIN_ID, code, message, exception);
multiStatus.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, code, exception.getLocalizedMessage(), exception));
status= multiStatus;
} else {
status= new Status(IStatus.ERROR, Activator.PLUGIN_ID, code, message, null);
}
throw new CoreException(status);
}
}

View file

@ -0,0 +1,182 @@
/********************************************************************************
* Copyright (c) 2016 IBM Corporation and others.
* 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:
* Wainer S. Moschetta (IBM) - initial API and implementation
********************************************************************************/
package org.eclipse.cdt.launch.remote;
import java.util.ArrayList;
import org.eclipse.cdt.internal.launch.remote.Activator;
import org.eclipse.cdt.internal.launch.remote.Messages;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.remote.core.IRemoteCommandShellService;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
import org.eclipse.remote.core.IRemoteServicesManager;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.ui.IRemoteUIConnectionService;
import org.eclipse.remote.ui.IRemoteUIConnectionWizard;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
public class RemoteUIHelper {
/**
* Open dialog to edit a remote connection.
*
* @param connection - the remote connection
* @param shell - the shell
*/
public static void editConnectionDialog(IRemoteConnection connection, Shell shell) {
if (connection == null) {
return;
}
IRemoteUIConnectionService uiConnServices = connection.getConnectionType().getService(IRemoteUIConnectionService.class);
IRemoteUIConnectionWizard wizard = uiConnServices.getConnectionWizard(shell);
wizard.setConnection(connection.getWorkingCopy());
IRemoteConnectionWorkingCopy connCopy = wizard.open();
if (connCopy != null) {
try {
connCopy.save();
} catch (RemoteConnectionException e) {
logError(e);
}
}
}
/**
* Open dialog for user to create a new connection.
*
* @param shell - the shell
*/
public static void newConnectionDialog(Shell shell) {
/*
* Evoke native new connection wizard and save connection
* if created by the user.
*/
class NewRemoteConnectionDialog extends Dialog {
private String title;
private Combo fConnSelection;
private IRemoteServicesManager manager;
protected NewRemoteConnectionDialog(Shell parentShell, String windowTitle) {
super(parentShell);
title = windowTitle;
manager = Activator.getService(IRemoteServicesManager.class);
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText(title);
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
Label label = new Label(composite, SWT.WRAP);
label.setText(Messages.RemoteCMainTab_New_conntype_combo_label);
GridData data = new GridData(GridData.GRAB_HORIZONTAL
| GridData.GRAB_VERTICAL
| GridData.HORIZONTAL_ALIGN_FILL
| GridData.VERTICAL_ALIGN_CENTER);
data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
label.setLayoutData(data);
label.setFont(parent.getFont());
fConnSelection = new Combo (composite, SWT.DROP_DOWN | SWT.READ_ONLY);
ArrayList<String> suitableConnections = new ArrayList<>();
for (IRemoteConnectionType type: manager.getAllConnectionTypes()) {
if (type.canAdd() &&
type.getConnectionServices().contains(
IRemoteCommandShellService.class.getName())) {
fConnSelection.setData(type.getName(), type.getId());
suitableConnections.add(type.getName());
}
}
fConnSelection.setItems(suitableConnections.toArray(new String[0]));
fConnSelection.select(0);
applyDialogFont(composite);
return composite;
}
@Override
protected void buttonPressed(int buttonId) {
if (buttonId == IDialogConstants.OK_ID) {
String connTypeId = (String) fConnSelection.getData(fConnSelection.getText());
IRemoteConnectionType connType = manager.getConnectionType(connTypeId);
IRemoteUIConnectionService fUIConnectionManager = connType.getService(IRemoteUIConnectionService.class);
IRemoteUIConnectionWizard wizard = fUIConnectionManager.getConnectionWizard(this.getShell());
IRemoteConnectionWorkingCopy wc = wizard.open();
if (wc != null) {
try {
wc.save();
} catch (RemoteConnectionException e) {
logError(e);
}
}
}
super.buttonPressed(buttonId);
}
}
NewRemoteConnectionDialog dlg = new NewRemoteConnectionDialog(shell,
Messages.RemoteCMainTab_New_title);
dlg.setBlockOnOpen(true);
dlg.open();
}
/**
* Get a property associated with the connection.
*
* @param connection - the connection
* @param property - the property's name
* @return the property's value or empty string if it is not set.
*/
public static String getConnectionProperty(IRemoteConnection connection, String property) {
String key = IRemoteConnectionHostConstants.PI_REMOTE_CDT + "." //$NON-NLS-1$
+ property;
return connection.getAttribute(key);
}
/**
* Associate a property with the connection.
*
* @param connection - the connection
* @param property - the property's name
* @param value the property's value
*/
public static void setConnectionProperty(IRemoteConnection connection, String property, String value) {
String key = IRemoteConnectionHostConstants.PI_REMOTE_CDT + "." //$NON-NLS-1$
+ property;
IRemoteConnectionWorkingCopy wc = connection.getWorkingCopy();
wc.setAttribute(key, value);
try {
wc.save();
} catch (RemoteConnectionException e) {
logError(e);
}
}
private static void logError(Exception e) {
Plugin plugin = Activator.getDefault();
ILog logger = plugin.getLog();
logger.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
e.getMessage(), e));
}
}

View file

@ -27,41 +27,28 @@ import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.internal.launch.remote.Activator; import org.eclipse.cdt.internal.launch.remote.Activator;
import org.eclipse.cdt.internal.launch.remote.Messages; import org.eclipse.cdt.internal.launch.remote.Messages;
import org.eclipse.cdt.launch.remote.IRemoteConnectionConfigurationConstants; import org.eclipse.cdt.launch.remote.IRemoteConnectionConfigurationConstants;
import org.eclipse.cdt.launch.remote.RSEHelper; import org.eclipse.cdt.launch.remote.RemoteHelper;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.IProcess;
import org.eclipse.rse.core.RSECorePlugin; import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.rse.services.shells.HostShellProcessAdapter; import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.rse.services.shells.IHostOutput; import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.rse.services.shells.IHostShell; import org.eclipse.remote.core.RemoteProcessAdapter;
import org.eclipse.rse.services.shells.IHostShellChangeEvent;
import org.eclipse.rse.services.shells.IHostShellOutputListener;
public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate { public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate {
@Override @Override
public void launch(ILaunchConfiguration config, String mode, public void launch(ILaunchConfiguration config, String mode,
ILaunch launch, IProgressMonitor monitor) throws CoreException { ILaunch launch, IProgressMonitor monitor) throws CoreException {
// Need to initialize RSE
if (!RSECorePlugin.isInitComplete(RSECorePlugin.INIT_MODEL)) {
monitor.subTask(Messages.RemoteRunLaunchDelegate_10);
try {
RSECorePlugin.waitForInitCompletion(RSECorePlugin.INIT_MODEL);
} catch (InterruptedException e) {
throw new CoreException(new Status(IStatus.ERROR,
getPluginID(), IStatus.OK, e.getLocalizedMessage(), e));
}
}
IPath exePath = checkBinaryDetails(config); IPath exePath = checkBinaryDetails(config);
Process remoteShellProcess = null; Process remoteShellProcess = null;
@ -71,7 +58,7 @@ public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate {
IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH,
""); //$NON-NLS-1$ ""); //$NON-NLS-1$
monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2); monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2);
RSEHelper.remoteFileDownload(config, launch, exePath.toString(), RemoteHelper.remoteFileDownload(config, launch, exePath.toString(),
remoteExePath, new SubProgressMonitor(monitor, 80)); remoteExePath, new SubProgressMonitor(monitor, 80));
// 2.Launch gdbserver on target // 2.Launch gdbserver on target
String gdbserverPortNumber = config String gdbserverPortNumber = config
@ -88,7 +75,7 @@ public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate {
IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_OPTIONS_DEFAULT); IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_OPTIONS_DEFAULT);
String commandArguments = gdbserverOptions + " " //$NON-NLS-1$ String commandArguments = gdbserverOptions + " " //$NON-NLS-1$
+ ":" + gdbserverPortNumber + " " //$NON-NLS-1$ //$NON-NLS-2$ + ":" + gdbserverPortNumber + " " //$NON-NLS-1$ //$NON-NLS-2$
+ RSEHelper.spaceEscapify(remoteExePath); + RemoteHelper.spaceEscapify(remoteExePath);
String arguments = getProgramArguments(config); String arguments = getProgramArguments(config);
String prelaunchCmd = config String prelaunchCmd = config
.getAttribute( .getAttribute(
@ -101,13 +88,13 @@ public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate {
// extending HostShellProcessAdapter here // extending HostShellProcessAdapter here
final GdbLaunch l = (GdbLaunch)launch; final GdbLaunch l = (GdbLaunch)launch;
IHostShell remoteShell = null; IRemoteProcess remoteShell = null;
try { try {
remoteShell = RSEHelper.execCmdInRemoteShell(config, prelaunchCmd, remoteShell = RemoteHelper.execCmdInRemoteShell(config, prelaunchCmd,
gdbserverCommand, commandArguments, gdbserverCommand, commandArguments,
new SubProgressMonitor(monitor, 5)); new SubProgressMonitor(monitor, 5));
} catch (Exception e1) { } catch (Exception e1) {
RSEHelper.abort(e1.getMessage(), e1, RemoteHelper.abort(e1.getMessage(), e1,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
} }
@ -121,23 +108,8 @@ public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate {
final Object lock = new Object(); final Object lock = new Object();
if (remoteShell != null) { if (remoteShell != null) {
remoteShell.addOutputListener(new IHostShellOutputListener() {
public void shellOutputChanged(IHostShellChangeEvent event) {
for (IHostOutput line : event.getLines()) {
if (line.getString().contains("Listening on port")) { //$NON-NLS-1$
synchronized (lock) {
gdbServerReady[0] = true;
lock.notifyAll();
}
break;
}
}
}
});
try { try {
remoteShellProcess = new HostShellProcessAdapter(remoteShell) { remoteShellProcess = new RemoteProcessAdapter(remoteShell) {
@Override @Override
public synchronized void destroy() { public synchronized void destroy() {
@ -168,13 +140,28 @@ public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate {
if (remoteShellProcess != null) { if (remoteShellProcess != null) {
remoteShellProcess.destroy(); remoteShellProcess.destroy();
} }
RSEHelper.abort(Messages.RemoteRunLaunchDelegate_7, e, RemoteHelper.abort(Messages.RemoteRunLaunchDelegate_7, e,
ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
} }
IProcess iProcess = DebugPlugin.newProcess(launch, remoteShellProcess, IProcess iProcess = DebugPlugin.newProcess(launch, remoteShellProcess,
Messages.RemoteRunLaunchDelegate_RemoteShell); Messages.RemoteRunLaunchDelegate_RemoteShell);
// Listen process' output to determine gdbserver is up and running.
IStreamsProxy streams = iProcess.getStreamsProxy();
IStreamMonitor monitorStream = streams.getOutputStreamMonitor();
monitorStream.addListener(new IStreamListener() {
@Override
public void streamAppended(String text, IStreamMonitor monitor) {
if (text.contains("Listening on port")) { //$NON-NLS-1$
synchronized (lock) {
gdbServerReady[0] = true;
lock.notifyAll();
}
monitor.removeListener(this);
}
}
});
// Now wait until gdbserver is up and running on the remote host // Now wait until gdbserver is up and running on the remote host
synchronized (lock) { synchronized (lock) {
while (gdbServerReady[0] == false) { while (gdbServerReady[0] == false) {
@ -196,7 +183,7 @@ public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate {
// Session disposed. // Session disposed.
} }
RSEHelper.abort(Messages.RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorMessage, null, RemoteHelper.abort(Messages.RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorMessage, null,
ICDTLaunchConfigurationConstants.ERR_DEBUGGER_NOT_INSTALLED); ICDTLaunchConfigurationConstants.ERR_DEBUGGER_NOT_INSTALLED);
} }
try { try {
@ -211,7 +198,7 @@ public class RemoteGdbLaunchDelegate extends GdbLaunchDelegate {
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP,
true); true);
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_HOST, wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_HOST,
RSEHelper.getRemoteHostname(config)); RemoteHelper.getRemoteHostname(config));
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_PORT, wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_PORT,
gdbserverPortNumber); gdbserverPortNumber);
wc.doSave(); wc.doSave();

View file

@ -30,7 +30,7 @@ import org.eclipse.cdt.internal.launch.remote.Activator;
import org.eclipse.cdt.internal.launch.remote.Messages; import org.eclipse.cdt.internal.launch.remote.Messages;
import org.eclipse.cdt.launch.AbstractCLaunchDelegate; import org.eclipse.cdt.launch.AbstractCLaunchDelegate;
import org.eclipse.cdt.launch.remote.IRemoteConnectionConfigurationConstants; import org.eclipse.cdt.launch.remote.IRemoteConnectionConfigurationConstants;
import org.eclipse.cdt.launch.remote.RSEHelper; import org.eclipse.cdt.launch.remote.RemoteHelper;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
@ -43,7 +43,6 @@ import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.osgi.util.NLS; import org.eclipse.osgi.util.NLS;
import org.eclipse.rse.core.RSECorePlugin;
public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
@ -67,17 +66,6 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
if (monitor == null) if (monitor == null)
monitor = new NullProgressMonitor(); monitor = new NullProgressMonitor();
if (!RSECorePlugin.isInitComplete(RSECorePlugin.INIT_MODEL)) {
monitor.subTask(Messages.RemoteRunLaunchDelegate_10);
try {
RSECorePlugin
.waitForInitCompletion(RSECorePlugin.INIT_MODEL);
} catch (InterruptedException e) {
throw new CoreException(new Status(IStatus.ERROR,
getPluginID(), IStatus.OK, e.getLocalizedMessage(),
e));
}
}
if (mode.equals(ILaunchManager.RUN_MODE)) { if (mode.equals(ILaunchManager.RUN_MODE)) {
monitor.beginTask(Messages.RemoteRunLaunchDelegate_0, 100); monitor.beginTask(Messages.RemoteRunLaunchDelegate_0, 100);
@ -85,11 +73,11 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
try { try {
// Download the binary to the remote before debugging. // Download the binary to the remote before debugging.
monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2); monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2);
RSEHelper.remoteFileDownload(config, launch, exePath.toString(), RemoteHelper.remoteFileDownload(config, launch, exePath.toString(),
remoteExePath, new SubProgressMonitor(monitor, 80)); remoteExePath, new SubProgressMonitor(monitor, 80));
// Use a remote shell to launch the binary. // Use a remote shell to launch the binary.
monitor.setTaskName(Messages.RemoteRunLaunchDelegate_12); monitor.setTaskName(Messages.RemoteRunLaunchDelegate_12);
remoteProcess = RSEHelper.remoteShellExec(config, prelaunchCmd, remoteProcess = RemoteHelper.remoteShellExec(config, prelaunchCmd,
remoteExePath, arguments, new SubProgressMonitor( remoteExePath, arguments, new SubProgressMonitor(
monitor, 20)); monitor, 20));
DebugPlugin.newProcess(launch, remoteProcess, DebugPlugin.newProcess(launch, remoteProcess,

View file

@ -31,7 +31,9 @@ import org.eclipse.cdt.internal.launch.remote.Activator;
import org.eclipse.cdt.internal.launch.remote.Messages; import org.eclipse.cdt.internal.launch.remote.Messages;
import org.eclipse.cdt.launch.remote.IRemoteConnectionConfigurationConstants; import org.eclipse.cdt.launch.remote.IRemoteConnectionConfigurationConstants;
import org.eclipse.cdt.launch.remote.IRemoteConnectionHostConstants; import org.eclipse.cdt.launch.remote.IRemoteConnectionHostConstants;
import org.eclipse.cdt.launch.remote.RSEHelper; import org.eclipse.cdt.launch.remote.RemoteHelper;
import org.eclipse.cdt.launch.remote.RemoteUIHelper;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
@ -41,15 +43,9 @@ import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.jface.window.Window; import org.eclipse.remote.core.IRemoteServicesManager;
import org.eclipse.rse.core.IRSESystemType; import org.eclipse.remote.ui.dialogs.RemoteResourceBrowser;
import org.eclipse.rse.core.RSECorePlugin;
import org.eclipse.rse.core.model.IHost;
import org.eclipse.rse.core.model.IPropertySet;
import org.eclipse.rse.files.ui.dialogs.SystemRemoteFileDialog;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
import org.eclipse.rse.ui.actions.SystemNewConnectionAction;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.ModifyListener;
@ -65,7 +61,6 @@ import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
public class RemoteCDSFMainTab extends CMainTab { public class RemoteCDSFMainTab extends CMainTab {
@ -80,9 +75,6 @@ public class RemoteCDSFMainTab extends CMainTab {
private static final String REMOTE_PATH_DEFAULT = EMPTY_STRING; private static final String REMOTE_PATH_DEFAULT = EMPTY_STRING;
private static final boolean SKIP_DOWNLOAD_TO_REMOTE_DEFAULT = false; private static final boolean SKIP_DOWNLOAD_TO_REMOTE_DEFAULT = false;
/* SystemConnectionPropertyPage id*/
private static final String SYSTEM_PAGE_ID = "org.eclipse.rse.SystemPropertyPage"; //$NON-NLS-1$
protected Button newRemoteConnectionButton; protected Button newRemoteConnectionButton;
protected Button editRemoteConnectionButton; protected Button editRemoteConnectionButton;
protected Button remoteConnectionPropertiesButton; protected Button remoteConnectionPropertiesButton;
@ -94,7 +86,6 @@ public class RemoteCDSFMainTab extends CMainTab {
protected Button skipDownloadButton; protected Button skipDownloadButton;
protected Button useLocalPathButton; protected Button useLocalPathButton;
SystemNewConnectionAction action = null;
private Text preRunText; private Text preRunText;
private Label preRunLabel; private Label preRunLabel;
@ -109,7 +100,7 @@ public class RemoteCDSFMainTab extends CMainTab {
// TODO Auto-generated method stub // TODO Auto-generated method stub
super.createControl(parent); super.createControl(parent);
Composite comp = (Composite) getControl(); Composite comp = (Composite) getControl();
/* The RSE Connection dropdown with New button. */ /* The Connection dropdown with New button. */
createVerticalSpacer(comp, 1); createVerticalSpacer(comp, 1);
createRemoteConnectionGroup(comp, 4); createRemoteConnectionGroup(comp, 4);
/* The remote binary location and skip download option */ /* The remote binary location and skip download option */
@ -315,78 +306,63 @@ public class RemoteCDSFMainTab extends CMainTab {
} }
protected void handleNewRemoteConnectionSelected() { protected void handleNewRemoteConnectionSelected() {
if (action == null) { RemoteUIHelper.newConnectionDialog(getControl().getShell());
action = new SystemNewConnectionAction(getControl().getShell(),
false, false, null);
}
try {
action.run();
} catch (Exception e) {
// Ignore
}
} }
/** /**
* Opens the <code>SystemConnectionPropertyPage</code> page for the selected connection. * Opens the <code>SystemConnectionPropertyPage</code> page for the selected connection.
*/ */
protected void handleEditRemoteConnectionSelected() { protected void handleEditRemoteConnectionSelected() {
IHost currentConnectionSelected = getCurrentConnection(); RemoteUIHelper.editConnectionDialog(getCurrentConnection(),
PreferenceDialog dialog = PreferencesUtil.createPropertyDialogOn(getControl().getShell(), currentConnectionSelected, SYSTEM_PAGE_ID, null, null); getControl().getShell());
if (dialog != null) {
dialog.open();
}
} }
protected IHost getCurrentConnection() { protected IRemoteConnection getCurrentConnection() {
int currentSelection = connectionCombo.getSelectionIndex(); int currentSelection = connectionCombo.getSelectionIndex();
String remoteConnection = currentSelection >= 0 ? connectionCombo String remoteConnection = currentSelection >= 0 ? connectionCombo
.getItem(currentSelection) : null; .getItem(currentSelection) : null;
return RSEHelper.getRemoteConnectionByName(remoteConnection); return RemoteHelper.getRemoteConnectionByName(remoteConnection);
} }
protected void handleRemoteBrowseSelected() { protected void handleRemoteBrowseSelected() {
IHost currentConnectionSelected = getCurrentConnection(); IRemoteConnection currentConnectionSelected = getCurrentConnection();
SystemRemoteFileDialog dlg = new SystemRemoteFileDialog(getControl() RemoteResourceBrowser b = new RemoteResourceBrowser(getControl().getShell(),
.getShell(), SWT.NONE);
Messages.RemoteCMainTab_Remote_Path_Browse_Button_Title, b.setConnection(currentConnectionSelected);
currentConnectionSelected); b.setTitle(Messages.RemoteCMainTab_Remote_Path_Browse_Button_Title);
dlg.setBlockOnOpen(true); b.open();
if (dlg.open() == Window.OK) { IFileStore selectedFile = b.getResource();
Object retObj = dlg.getSelectedObject(); if (selectedFile != null) {
if (retObj instanceof IRemoteFile) { String absPath = selectedFile.toURI().getPath();
IRemoteFile selectedFile = (IRemoteFile) retObj; if (selectedFile.fetchInfo().isDirectory()) {
String absPath = selectedFile.getAbsolutePath();
if (selectedFile.isDirectory()) {
// The user selected a destination folder to upload the binary // The user selected a destination folder to upload the binary
// Append the Program name as the default file destination // Append the Program name as the default file destination
IPath appPath = new Path(fProgText.getText().trim()); IPath appPath = new Path(fProgText.getText().trim());
String lastSegment = appPath.lastSegment(); String lastSegment = appPath.lastSegment();
if (lastSegment != null && lastSegment.trim().length() > 0) { if (lastSegment != null && lastSegment.trim().length() > 0) {
IPath remotePath = new Path(selectedFile.getAbsolutePath()).append(lastSegment.trim()); IPath remotePath = new Path(absPath).append(lastSegment.trim());
absPath = remotePath.toPortableString(); absPath = remotePath.toPortableString();
} }
} }
remoteProgText.setText(absPath); remoteProgText.setText(absPath);
} }
}
} }
protected void handleRemoteConnectionPropertiesSelected() { protected void handleRemoteConnectionPropertiesSelected() {
class RemoteConnectionPropertyDialog extends Dialog { class RemoteConnectionPropertyDialog extends Dialog {
private IHost fHost; private IRemoteConnection fHost;
boolean fbLocalHost; boolean fbLocalHost;
private Button fSkipDownloadBtn; private Button fSkipDownloadBtn;
private Text fWSRoot; private Text fWSRoot;
private String fDialogTitle; private String fDialogTitle;
public RemoteConnectionPropertyDialog(Shell parentShell, public RemoteConnectionPropertyDialog(Shell parentShell,
String dialogTitle, IHost host) { String dialogTitle, IRemoteConnection host) {
super(parentShell); super(parentShell);
fDialogTitle = dialogTitle; fDialogTitle = dialogTitle;
fHost = host; fHost = host;
fbLocalHost = fHost.getSystemType().isLocal(); IRemoteServicesManager remoteServicesManager = Activator.getService(IRemoteServicesManager.class);
fbLocalHost = (fHost.getConnectionType() == remoteServicesManager.getLocalConnectionType());
} }
@Override @Override
@ -418,21 +394,17 @@ public class RemoteCDSFMainTab extends CMainTab {
fSkipDownloadBtn fSkipDownloadBtn
.setText(Messages.RemoteCMainTab_Properties_Skip_default); .setText(Messages.RemoteCMainTab_Properties_Skip_default);
if (!fbLocalHost) { if (!fbLocalHost) {
IPropertySet propertySet = fHost String value = RemoteUIHelper.getConnectionProperty(fHost,
.getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); IRemoteConnectionHostConstants.REMOTE_WS_ROOT);
if (propertySet != null) { if(!value.isEmpty()) {
String value = propertySet
.getPropertyValue(IRemoteConnectionHostConstants.REMOTE_WS_ROOT);
if (value != null) {
fWSRoot.setText(value); fWSRoot.setText(value);
} }
fSkipDownloadBtn fSkipDownloadBtn
.setSelection(Boolean .setSelection(Boolean
.valueOf( .valueOf(
propertySet RemoteUIHelper.getConnectionProperty(fHost,
.getPropertyValue(IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD)) IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD))
.booleanValue()); .booleanValue());
}
} else { } else {
fSkipDownloadBtn.setEnabled(false); fSkipDownloadBtn.setEnabled(false);
fWSRoot.setEnabled(false); fWSRoot.setEnabled(false);
@ -444,26 +416,18 @@ public class RemoteCDSFMainTab extends CMainTab {
@Override @Override
protected void buttonPressed(int buttonId) { protected void buttonPressed(int buttonId) {
if (!fbLocalHost && (buttonId == IDialogConstants.OK_ID)) { if (!fbLocalHost && (buttonId == IDialogConstants.OK_ID)) {
IPropertySet propertySet = fHost RemoteUIHelper.setConnectionProperty(fHost,
.getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT);
if (propertySet == null) {
propertySet = fHost
.createPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT);
}
propertySet.addProperty(
IRemoteConnectionHostConstants.REMOTE_WS_ROOT, IRemoteConnectionHostConstants.REMOTE_WS_ROOT,
fWSRoot.getText()); fWSRoot.getText());
propertySet RemoteUIHelper.setConnectionProperty(fHost,
.addProperty(
IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD, IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD,
Boolean.toString(fSkipDownloadBtn Boolean.toString(fSkipDownloadBtn
.getSelection())); .getSelection()));
fHost.commit();
} }
super.buttonPressed(buttonId); super.buttonPressed(buttonId);
} }
} }
IHost currentConnectionSelected = getCurrentConnection(); IRemoteConnection currentConnectionSelected = getCurrentConnection();
RemoteConnectionPropertyDialog dlg = new RemoteConnectionPropertyDialog( RemoteConnectionPropertyDialog dlg = new RemoteConnectionPropertyDialog(
getControl().getShell(), getControl().getShell(),
Messages.RemoteCMainTab_Properties_title, Messages.RemoteCMainTab_Properties_title,
@ -473,20 +437,10 @@ public class RemoteCDSFMainTab extends CMainTab {
} }
protected void updateConnectionPulldown() { protected void updateConnectionPulldown() {
if (!RSECorePlugin.isInitComplete(RSECorePlugin.INIT_MODEL))
try {
RSECorePlugin.waitForInitCompletion(RSECorePlugin.INIT_MODEL);
} catch (InterruptedException e) {
return;
}
// already initialized
connectionCombo.removeAll(); connectionCombo.removeAll();
IHost[] connections = RSEHelper.getSuitableConnections(); IRemoteConnection[] connections = RemoteHelper.getSuitableConnections();
for (int i = 0; i < connections.length; i++) { for (int i = 0; i < connections.length; i++) {
IRSESystemType sysType = connections[i].getSystemType(); connectionCombo.add(connections[i].getName());
if (sysType != null && sysType.isEnabled()) {
connectionCombo.add(connections[i].getAliasName());
}
} }
if (connections.length > 0) { if (connections.length > 0) {
@ -505,13 +459,11 @@ public class RemoteCDSFMainTab extends CMainTab {
return; return;
} }
boolean bEnable = false; boolean bEnable = false;
IHost currentConnectionSelected = getCurrentConnection(); IRemoteConnection currentConnectionSelected = getCurrentConnection();
if (currentConnectionSelected != null) { if (currentConnectionSelected != null &&
IRSESystemType sysType = currentConnectionSelected.getSystemType(); currentConnectionSelected.getConnectionType().canEdit()) {
if (sysType != null && sysType.isEnabled() && !sysType.isLocal()) {
bEnable = true; bEnable = true;
} }
}
remoteConnectionPropertiesButton.setEnabled(bEnable); remoteConnectionPropertiesButton.setEnabled(bEnable);
editRemoteConnectionButton.setEnabled(bEnable); editRemoteConnectionButton.setEnabled(bEnable);
} }
@ -604,14 +556,14 @@ public class RemoteCDSFMainTab extends CMainTab {
} }
if ((skipDownloadButton != null) && !skipDownloadButton.isDisposed()) { if ((skipDownloadButton != null) && !skipDownloadButton.isDisposed()) {
skipDownloadButton.setSelection(getDefaultSkipDownload()); skipDownloadButton.setSelection(getDefaultSkipDownload());
if (RSEHelper.getFileSubsystem(getCurrentConnection()) == null) { if (RemoteHelper.getFileSubsystem(getCurrentConnection()) == null) {
skipDownloadButton.setEnabled(false); skipDownloadButton.setEnabled(false);
} else { } else {
skipDownloadButton.setEnabled(true); skipDownloadButton.setEnabled(true);
} }
} }
if ((remoteBrowseButton != null) && !remoteBrowseButton.isDisposed()) { if ((remoteBrowseButton != null) && !remoteBrowseButton.isDisposed()) {
if (RSEHelper.getFileSubsystem(getCurrentConnection()) == null) { if (RemoteHelper.getFileSubsystem(getCurrentConnection()) == null) {
remoteBrowseButton.setEnabled(false); remoteBrowseButton.setEnabled(false);
} else { } else {
remoteBrowseButton.setEnabled(true); remoteBrowseButton.setEnabled(true);
@ -633,35 +585,27 @@ public class RemoteCDSFMainTab extends CMainTab {
} }
private String getRemoteWSRoot() { private String getRemoteWSRoot() {
IHost host = getCurrentConnection(); IRemoteConnection host = getCurrentConnection();
if(host != null) { if(host != null) {
IPropertySet propertySet = host String value = RemoteUIHelper.getConnectionProperty(host,
.getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); IRemoteConnectionHostConstants.REMOTE_WS_ROOT);
if (propertySet != null) { if(!value.isEmpty()) {
String value = propertySet
.getPropertyValue(IRemoteConnectionHostConstants.REMOTE_WS_ROOT);
if (value != null) {
return value; return value;
} }
} }
}
return ""; //$NON-NLS-1$ return ""; //$NON-NLS-1$
} }
private boolean getDefaultSkipDownload() { private boolean getDefaultSkipDownload() {
IHost host = getCurrentConnection(); IRemoteConnection host = getCurrentConnection();
if (host != null) { if (host != null) {
if (RSEHelper.getFileSubsystem(host) == null) { if(RemoteHelper.getFileSubsystem(host) == null){
return true; return true;
} }
IPropertySet propertySet = host String value = RemoteUIHelper.getConnectionProperty(host,
.getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD);
if (propertySet != null) { if(!value.isEmpty()) {
return Boolean return Boolean.valueOf(value).booleanValue();
.valueOf(
propertySet
.getPropertyValue(IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD))
.booleanValue();
} }
} }
return SKIP_DOWNLOAD_TO_REMOTE_DEFAULT; return SKIP_DOWNLOAD_TO_REMOTE_DEFAULT;

View file

@ -10,7 +10,7 @@ http://www.eclipse.org/legal/epl-v10.html
Contributors: Contributors:
Martin Oberhuber (Wind River) - initial API and implementation Martin Oberhuber (Wind River) - initial API and implementation
--> -->
<toc link_to="../org.eclipse.rse.doc.user/toc.xml#rse_user_extensions" <toc link_to="../org.eclipse.cdt.doc.user/toc.xml#cdt_Tasks_Anchor"
label="Launching Remote C/C++ Applications"> label="Launching Remote C/C++ Applications">
<topic label="Launching Remote C/C++ Applications" href="remotecdt.html"/> <topic label="Launching Remote C/C++ Applications" href="remotecdt.html"/>
</toc> </toc>