diff options
Diffstat (limited to 'target_explorer')
6 files changed, 164 insertions, 32 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/services/FileTransferService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/services/FileTransferService.java index e0d023b3a..418991906 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/services/FileTransferService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/services/FileTransferService.java @@ -19,6 +19,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IPath; @@ -51,6 +52,53 @@ import org.eclipse.tcf.util.TCFFileOutputStream; */ public class FileTransferService { + /** + * Returns the target path file attribute. + * + * @param peer The peer, must not be <code>null</code>. + * @param channel The channel or <code>null</code>. + * @param item The file transfer item, must not be <code>null</code>. + * + * @return The target path file attributes or <code>null</code>. + */ + public static FileAttrs getRemoteFileAttrs(IPeer peer, IChannel channel, IFileTransferItem item) { + + final AtomicReference<FileAttrs> attrs = new AtomicReference<FileAttrs>(); + + boolean ownChannel = false; + IFileSystem fileSystem; + try { + if (channel == null) { + ownChannel = true; + channel = Operation.openChannel(peer); + } + fileSystem = Operation.getBlockingFileSystem(channel); + + Assert.isNotNull(fileSystem); + + IPath targetPath = item.getTargetPath(); + if (targetPath != null) { + final AtomicReference<FileSystemException> error = new AtomicReference<FileSystemException>(); + + fileSystem.stat(targetPath.toString(), new IFileSystem.DoneStat() { + @Override + public void doneStat(IToken token, FileSystemException e, FileAttrs a) { + error.set(e); + attrs.set(e == null ? a : null); + } + }); + } + if (ownChannel) { + closeChannel(peer, channel); + } + } + catch (Exception e) { + attrs.set(null); + } + + return attrs.get(); + } + /** * Transfer a file between host and target depending on the {@link IFileTransferItem} data. * diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbLaunchDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbLaunchDelegate.java index bad872159..d5e333143 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbLaunchDelegate.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbLaunchDelegate.java @@ -15,6 +15,7 @@ package org.eclipse.tcf.te.tcf.launch.cdt.launching; +import java.io.IOException; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicBoolean; @@ -34,6 +35,7 @@ import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.osgi.util.NLS; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.te.runtime.callback.Callback; import org.eclipse.tcf.te.tcf.core.streams.StreamsDataReceiver; @@ -59,7 +61,11 @@ public class TEGdbLaunchDelegate extends GdbLaunchDelegate { boolean skipDownload = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, false); if (!skipDownload) { - TEHelper.remoteFileTransfer(peer, exePath.toString(), remoteExePath, new SubProgressMonitor(monitor, 80)); + try { + TEHelper.remoteFileTransfer(peer, exePath.toString(), remoteExePath, new SubProgressMonitor(monitor, 80)); + } catch (IOException e) { + abort(NLS.bind(Messages.RemoteGdbLaunchDelegate_filetransferFailed, e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); + } } // 2.Launch gdbserver on target diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TERunLaunchDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TERunLaunchDelegate.java index 25b7e6cbb..950563f4d 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TERunLaunchDelegate.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TERunLaunchDelegate.java @@ -9,8 +9,11 @@ *******************************************************************************/ package org.eclipse.tcf.te.tcf.launch.cdt.launching; +import java.io.IOException; + import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.debug.core.CDebugUtils; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.dsf.gdb.launching.LaunchUtils; import org.eclipse.cdt.launch.AbstractCLaunchDelegate; import org.eclipse.core.runtime.CoreException; @@ -19,6 +22,7 @@ import org.eclipse.core.runtime.IProgressMonitor; 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.tcf.protocol.IPeer; import org.eclipse.tcf.te.runtime.callback.Callback; import org.eclipse.tcf.te.tcf.launch.cdt.activator.Activator; @@ -30,9 +34,8 @@ import org.eclipse.tcf.te.tcf.launch.cdt.utils.TERunProcess; public class TERunLaunchDelegate extends AbstractCLaunchDelegate { @SuppressWarnings("unused") - @Override - public void launch(ILaunchConfiguration config, String mode, - ILaunch launch, IProgressMonitor monitor) throws CoreException { + @Override + public void launch(ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { IPath exePath = checkBinaryDetails(config); if (exePath != null) { // -1. Initialize TE @@ -40,35 +43,29 @@ public class TERunLaunchDelegate extends AbstractCLaunchDelegate { // 0. Get the peer from the launch configuration IPeer peer = TEHelper.getCurrentConnection(config).getPeer(); // 1.Download binary if needed - String remoteExePath = config.getAttribute( - IRemoteTEConfigurationConstants.ATTR_REMOTE_PATH, ""); //$NON-NLS-1$ + String remoteExePath = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_REMOTE_PATH, ""); //$NON-NLS-1$ monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2); - boolean skipDownload = config - .getAttribute( - IRemoteTEConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, - false); + boolean skipDownload = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, false); if (!skipDownload) { - TEHelper.remoteFileTransfer(peer, exePath.toString(), - remoteExePath, new SubProgressMonitor(monitor, 80)); + try { + TEHelper.remoteFileTransfer(peer, exePath.toString(), remoteExePath, new SubProgressMonitor(monitor, 80)); + } catch (IOException e) { + abort(NLS.bind(Messages.RemoteGdbLaunchDelegate_filetransferFailed, e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); + } } + // 2. Run the binary monitor.setTaskName(Messages.RemoteRunLaunchDelegate_12); String arguments = getProgramArguments(config); - String prelaunchCmd = config.getAttribute( - IRemoteTEConfigurationConstants.ATTR_PRERUN_COMMANDS, ""); //$NON-NLS-1$ + String prelaunchCmd = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_PRERUN_COMMANDS, ""); //$NON-NLS-1$ - TEHelper.launchCmd(peer, prelaunchCmd, null, - new SubProgressMonitor(monitor, 2), new Callback()); - new TERunProcess(launch, remoteExePath, arguments, - renderProcessLabel(exePath.toOSString()), peer, - new SubProgressMonitor(monitor, 20)); + TEHelper.launchCmd(peer, prelaunchCmd, null, new SubProgressMonitor(monitor, 2), new Callback()); + new TERunProcess(launch, remoteExePath, arguments, renderProcessLabel(exePath.toOSString()), peer, new SubProgressMonitor(monitor, 20)); } - } - protected IPath checkBinaryDetails(final ILaunchConfiguration config) - throws CoreException { + protected IPath checkBinaryDetails(final ILaunchConfiguration config) throws CoreException { // First verify we are dealing with a proper project. ICProject project = CDebugUtils.verifyCProject(config); // Now verify we know the program to debug. diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.java index bb6bbbc3c..d42d5ca5a 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.java @@ -48,6 +48,7 @@ public class Messages extends NLS { public static String RemoteCMainTab_Properties_Location; public static String RemoteCMainTab_Properties_Skip_default; + public static String RemoteGdbLaunchDelegate_filetransferFailed; public static String RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorMessage; public static String RemoteRunLaunchDelegate_0; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.properties index e96394974..51cf053cc 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.properties @@ -52,5 +52,6 @@ RemoteCMainTab_Properties=Properties... RemoteCMainTab_Properties_title=Properties RemoteCMainTab_Properties_Location=Remote workspace location: RemoteCMainTab_Properties_Skip_default=Skip download to target path by default +RemoteGdbLaunchDelegate_filetransferFailed=Failed to download application image to target. Possibly caused by: {0} RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorMessage=Could not start gdbserver on the remote host. See console output for more details. TCFPeerSelector_0=Connection: diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TEHelper.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TEHelper.java index e6316bf9b..702dac1bc 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TEHelper.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TEHelper.java @@ -11,6 +11,10 @@ package org.eclipse.tcf.te.tcf.launch.cdt.utils; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -19,6 +23,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Path; @@ -28,6 +33,7 @@ import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.osgi.util.NLS; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.Protocol; +import org.eclipse.tcf.services.IFileSystem; import org.eclipse.tcf.te.core.utils.text.StringUtil; import org.eclipse.tcf.te.runtime.callback.Callback; import org.eclipse.tcf.te.runtime.concurrent.util.ExecutorsUtil; @@ -56,15 +62,87 @@ import org.eclipse.tcf.te.tcf.processes.core.launcher.ProcessLauncher; public class TEHelper { - public static void remoteFileTransfer(IPeer peer, String localFilePath, String remoteFilePath, SubProgressMonitor monitor) { - monitor.beginTask(Messages.RemoteRunLaunchDelegate_2 + " " + localFilePath + " to " + remoteFilePath, 100); //$NON-NLS-1$ //$NON-NLS-2$ + public static void remoteFileTransfer(IPeer peer, String localFilePath, String remoteFilePath, SubProgressMonitor monitor) throws IOException { + // Copy the host side file to a temporary location first before copying to the target, + // if the file size of the files are the same. If the remote file system is NFS mounted + // from the host, we end up with a truncated file otherwise. + boolean copyViaTemp = true; + File tempFile = null; + + // Create the file transfer item FileTransferItem item = new FileTransferItem(new Path(localFilePath), new Path(remoteFilePath)); item.setProperty(IFileTransferItem.PROPERTY_DIRECTION, "" + IFileTransferItem.HOST_TO_TARGET); //$NON-NLS-1$ + + // Get the remote path file attributes + IFileSystem.FileAttrs attrs = FileTransferService.getRemoteFileAttrs(peer, null, item); + if (attrs != null) { + IPath hostPath = item.getHostPath(); + if (hostPath.toFile().canRead()) { + copyViaTemp = attrs.size == hostPath.toFile().length(); + } + } + + // Copy the host file to a temporary location if needed + if (copyViaTemp) { + + monitor.beginTask(Messages.RemoteRunLaunchDelegate_2 + " " + localFilePath + " to " + remoteFilePath, 200); //$NON-NLS-1$ //$NON-NLS-2$ + + try { + IPath hostPath = item.getHostPath(); + tempFile = File.createTempFile(Long.toString(System.nanoTime()), null); + + long tick = hostPath.toFile().length() / 100; + + FileInputStream in = new FileInputStream(hostPath.toFile()); + try { + FileOutputStream out = new FileOutputStream(tempFile); + try { + int count; + long tickCount = 0; + byte[] buf = new byte[4096]; + while ((count = in.read(buf)) > 0) { + out.write(buf, 0, count); + tickCount += count; + if (tickCount >= tick) { + monitor.worked(1); + tickCount = 0; + } + } + } + finally { + out.close(); + } + } + finally { + in.close(); + } + } + catch (IOException e) { + // In case of an exception, make sure that the temporary file + // is removed before re-throwing the exception + if (tempFile != null) tempFile.delete(); + // Also the monitor needs to be marked done + monitor.done(); + // Re-throw the exception finally + throw e; + } + + // Recreate the file transfer item to take the temporary file as input + item = new FileTransferItem(new Path(tempFile.getAbsolutePath()), new Path(remoteFilePath)); + item.setProperty(IFileTransferItem.PROPERTY_DIRECTION, "" + IFileTransferItem.HOST_TO_TARGET); //$NON-NLS-1$ + } else { + monitor.beginTask(Messages.RemoteRunLaunchDelegate_2 + " " + localFilePath + " to " + remoteFilePath, 100); //$NON-NLS-1$ //$NON-NLS-2$ + } + + // Transfer the file to the target final Callback callback = new Callback(); FileTransferService.transfer(peer, null, item, monitor, callback); // Wait till the step finished, an execution occurred or the // user hit cancel on the progress monitor. ExecutorsUtil.waitAndExecute(0, callback.getDoneConditionTester(null)); + + // Remove the temporary file + if (tempFile != null) tempFile.delete(); } public static IPeerNode getPeerNode(final String peerId) { @@ -73,9 +151,7 @@ public class TEHelper { final Runnable runnable = new Runnable() { @Override public void run() { - parent.set(ModelManager.getPeerModel() - .getService(IPeerModelLookupService.class) - .lkupPeerModelById(peerId)); + parent.set(ModelManager.getPeerModel().getService(IPeerModelLookupService.class).lkupPeerModelById(peerId)); } }; Protocol.invokeAndWait(runnable); @@ -146,8 +222,10 @@ public class TEHelper { Runnable runnable = new Runnable() { @Override public void run() { - if (ITransportTypes.TRANSPORT_TYPE_TCP.equals(peer.getTransportName()) || ITransportTypes.TRANSPORT_TYPE_SSL.equals(peer.getTransportName())) { - isLocalhost.set(IPAddressUtil.getInstance().isLocalHost(peer.getAttributes().get(IPeer.ATTR_IP_HOST))); + if (ITransportTypes.TRANSPORT_TYPE_TCP.equals(peer.getTransportName()) || ITransportTypes.TRANSPORT_TYPE_SSL + .equals(peer.getTransportName())) { + isLocalhost.set(IPAddressUtil.getInstance().isLocalHost(peer + .getAttributes().get(IPeer.ATTR_IP_HOST))); } } }; @@ -156,8 +234,8 @@ public class TEHelper { else Protocol.invokeAndWait(runnable); if (isLocalhost.get()) { - container.setProperty(ITerminalsConnectorConstants.PROP_LINE_SEPARATOR, - Host.isWindowsHost() ? ILineSeparatorConstants.LINE_SEPARATOR_CRLF : ILineSeparatorConstants.LINE_SEPARATOR_LF); + container.setProperty(ITerminalsConnectorConstants.PROP_LINE_SEPARATOR, Host + .isWindowsHost() ? ILineSeparatorConstants.LINE_SEPARATOR_CRLF : ILineSeparatorConstants.LINE_SEPARATOR_LF); } } @@ -241,7 +319,8 @@ public class TEHelper { * 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 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 { |