blob: 7817259955b1adb18d550e220f6c2e4b5bb487a4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2016 MontaVista Software, LLC. 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:
* Anna Dushistova (MontaVista) - initial API and implementation
*******************************************************************************/
package org.eclipse.tcf.te.tcf.launch.cdt.launching;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.launching.LaunchUtils;
import org.eclipse.cdt.launch.AbstractCLaunchDelegate2;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.osgi.util.NLS;
import org.eclipse.tcf.protocol.IPeer;
import org.eclipse.tcf.te.tcf.launch.cdt.activator.Activator;
import org.eclipse.tcf.te.tcf.launch.cdt.interfaces.IRemoteTEConfigurationConstants;
import org.eclipse.tcf.te.tcf.launch.cdt.nls.Messages;
import org.eclipse.tcf.te.tcf.launch.cdt.utils.TEHelper;
import org.eclipse.tcf.te.tcf.launch.cdt.utils.TERunProcess;
public class TERunLaunchDelegate extends AbstractCLaunchDelegate2 {
public TERunLaunchDelegate() {
super(false);
}
@SuppressWarnings("unused")
@Override
public void launch(ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
IPath exePath = checkBinaryDetails(config);
if (exePath != null) {
// -1. Initialize TE
Activator.getDefault().initializeTE();
// 0. Get the peer from the launch configuration
IPeer peer = TEHelper.getCurrentConnection(config).getPeer();
// 1.1. If there are commands to run before, create a script for them
String remoteExePath = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_REMOTE_PATH, ""); //$NON-NLS-1$
String arguments = getProgramArguments(config);
String remoteLaunchCommand = remoteExePath.replaceAll("\\r", ""); //$NON-NLS-1$ //$NON-NLS-2$
if (arguments != null && !arguments.equals("")) { //$NON-NLS-1$
remoteLaunchCommand += " " + arguments.replaceAll("\\r", " ").replaceAll("\\n", " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
IPath remotePrerunScriptPath = null;
boolean launchAsRemoteUser = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_LAUNCH_REMOTE_USER, false);
String userId = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_REMOTE_USER_ID, (String)null);
String prerunCommands = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_PRERUN_COMMANDS, (String)null);
if ( (prerunCommands != null && prerunCommands.trim().length() > 0) ||
(launchAsRemoteUser && userId != null && userId.trim().length() > 0) ) {
if (prerunCommands == null) { prerunCommands = ""; } //$NON-NLS-1$
SimpleDateFormat formatter = new SimpleDateFormat ("HH-mm-ss-S", Locale.US); //$NON-NLS-1$
String prerunScriptNamePreffix = formatter.format( Long.valueOf(Calendar.getInstance().getTime().getTime()) );
String prerunScriptName = prerunScriptNamePreffix + "_" + exePath.toFile().getName() + ".sh"; //$NON-NLS-1$ //$NON-NLS-2$
IPath localTempLocation = Activator.getDefault().getStateLocation().append("prerun_commands_scripts"); //$NON-NLS-1$
if (!localTempLocation.toFile().exists()) localTempLocation.toFile().mkdirs();
IPath prerunScriptLocation = localTempLocation.append(prerunScriptName);
if (prerunScriptLocation.toFile().exists()) prerunScriptLocation.toFile().delete();
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(prerunScriptLocation.toFile()));
writer.write(NLS.bind(TEHelper.getPrerunTemplateContent(peer), prerunCommands.replaceAll("\\r", ""), remoteLaunchCommand)); //$NON-NLS-1$ //$NON-NLS-2$
} catch (Exception e) {
abort(NLS.bind(Messages.TEGdbAbstractLaunchDelegate_prerunScriptCreationFailed, prerunScriptLocation.toString(), e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) { /* Ignored on purpose. */ }
}
}
// Grant execution permission
prerunScriptLocation.toFile().setExecutable(true, false);
// Download the script to the target
remotePrerunScriptPath = new Path("/tmp").append(prerunScriptName); //$NON-NLS-1$
try {
TEHelper.remoteFileTransfer(peer, prerunScriptLocation.toString(), remotePrerunScriptPath.toString(), new SubProgressMonitor(monitor, 80));
} catch (IOException e) {
abort(NLS.bind(Messages.TEGdbAbstractLaunchDelegate_prerunScriptTransferFailed, remotePrerunScriptPath.toString(), e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST);
} finally {
// Remove local temporal script
prerunScriptLocation.toFile().delete();
}
}
// 1.2. Download binary if needed
monitor.setTaskName(Messages.TEGdbAbstractLaunchDelegate_downloading);
boolean skipDownload = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, false);
if (!skipDownload) {
try {
TEHelper.remoteFileTransfer(peer, exePath.toString(), remoteExePath, new SubProgressMonitor(monitor, 80));
} catch (IOException e) {
abort(NLS.bind(Messages.TEGdbAbstractLaunchDelegate_filetransferFailed, e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST);
}
}
// 2. Run the binary
monitor.setTaskName(Messages.TEGdbAbstractLaunchDelegate_starting_debugger);
Map<String,String> env = config.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<String,String>)null);
if (remotePrerunScriptPath != null) {
// Pass the user id as an argument to the script
String launchArguments = ""; //$NON-NLS-1$
if (launchAsRemoteUser && userId != null && userId.trim().length() > 0) {
launchArguments = "-u__ " + userId; //$NON-NLS-1$
}
new TERunProcess(launch, remotePrerunScriptPath.toString(), launchArguments, env, renderProcessLabel(exePath.toString()), peer, new SubProgressMonitor(monitor, 20));
} else {
new TERunProcess(launch, remoteExePath, arguments, env, renderProcessLabel(exePath.toString()), peer, new SubProgressMonitor(monitor, 20));
}
}
}
protected IPath checkBinaryDetails(final ILaunchConfiguration config) throws CoreException {
// First verify we are dealing with a proper project.
ICProject project = verifyCProject(config);
// Now verify we know the program to debug.
IPath exePath = LaunchUtils.verifyProgramPath(config, project);
// Finally, make sure the program is a proper binary.
LaunchUtils.verifyBinary(config, exePath);
return exePath;
}
protected String getProgramArguments(ILaunchConfiguration config) throws CoreException {
return org.eclipse.cdt.launch.LaunchUtils.getProgramArguments(config);
}
protected String renderProcessLabel(String commandLine) {
String format = "{0} ({1})"; //$NON-NLS-1$
String timestamp = DateFormat.getInstance().format(new Date(System.currentTimeMillis()));
return MessageFormat.format(format, new Object[]{commandLine, timestamp});
}
/* (non-Javadoc)
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate2#getPluginID()
*/
@Override
protected String getPluginID() {
return Activator.getUniqueIdentifier();
}
}